如何在python中将异构列表列表压缩成单个列表?

How to flatten a hetrogenous list of list into a single list in python?

我有一个对象列表,其中的对象可以是列表或标量。我想要一个只有标量的扁平列表。如:

1
2
L = [35,53,[525,6743],64,63,[743,754,757]]
outputList = [35,53,525,6743,64,63,743,754,757]

P.S.这个问题的答案不适用于异类列表。扁平化python中的浅列表


这里是一个相对简单的递归版本,它将使列表的任何深度变平。

1
2
3
4
5
6
7
8
9
10
11
12
l = [35,53,[525,6743],64,63,[743,754,757]]

def flatten(xs):
    result = []
    if isinstance(xs, (list, tuple)):
        for x in xs:
            result.extend(flatten(x))
    else:
        result.append(xs)
    return result

print flatten(l)


1
2
3
4
5
6
7
8
9
10
11
12
>>> data = [35,53,[525,6743],64,63,[743,754,757]]
>>> def flatten(L):
        for item in L:
            if isinstance(item,list):
                for subitem in item:
                    yield subitem
            else:
                yield item


>>> list(flatten(data))
[35, 53, 525, 6743, 64, 63, 743, 754, 757]

这里有一个一行代码高尔夫版本(它看起来不太好:d)

1
2
>>> [y for x in data for y in (x if isinstance(x,list) else [x])]
[35, 53, 525, 6743, 64, 63, 743, 754, 757]


它可以用numpy在一行中整齐地完成。

1
2
import numpy as np
np.hstack(l)

你最后会有一天

1
array([  35,   53,  525, 6743,   64,   63,  743,  754,  757])


1
2
3
4
5
6
7
8
l = [35,53,[525,6743],64,63,[743,754,757]]
outputList = []

for i in l:
    if isinstance(i, list):
        outputList.extend(i)
    else:
        outputList.append(i)


1
2
3
4
5
6
7
8
9
outputList = []
for e in l:
    if type(e) == list:
        outputList += e
    else:
        outputList.append(e)

>>> outputList
[35, 53, 525, 6743, 64, 63, 743, 754, 757]


根据你提到的问题,这里有一条单行线:

1
list(itertools.chain(*((sl if isinstance(sl, list) else [sl]) for sl in l)))

更新:以及完全基于迭代器的版本:

1
2
from itertools import imap, chain
list(chain.from_iterable(imap(lambda x: x if isinstance(x, list) else [x], l)))


答案很简单。利用递归。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def flatten(nst_lst, final_list):

    for val in nst_lst:
        if isinstance(val, list):
            flatten(val, final_list)
        else:
            final_list.append(val)
    return final_list

#Sample usage
fl_list = []
lst_to_flatten = [["this",["a",["thing"],"a"],"is"],["a","easy"]]

print(flatten(lst_to_flatten, fl_list))


此解决方案仅适用于您的特定情况(列表中的scalar),并假定scalar为整数。这是一个可怕的解决方案,但它是难以置信的短。

1
outputlist = map(int,",".split(str(L).replace("[","").replace("]","")))


1
2
3
4
5
6
>>> L = [35,53,[525,6743],64,63,[743,754,757]]
>>> K = []
>>> [K.extend([i]) if type(i) == int else K.extend(i) for i in L ]
[None, None, None, None, None, None]
>>> K
[35, 53, 525, 6743, 64, 63, 743, 754, 757]


允许无限树深的递归函数:

1
2
3
4
5
6
7
8
9
10
def flatten(l):
    if isinstance(l,(list,tuple)):
        if len(l):
            return flatten(l[0]) + flatten(l[1:])
        return []
    else:
        return [l]

>>>flatten([35,53,[525,[1,2],6743],64,63,[743,754,757]])
[35, 53, 525, 1, 2, 6743, 64, 63, 743, 754, 757]

我试图避免isInstance以允许使用泛型类型,但旧版本将在字符串上无限循环。现在它正确地扁平字符串(现在不是按字符,而是假装字符串是标量)。


1
2
3
4
5
6
7
def nchain(iterable):
    for elem in iterable:
        if type(elem) is list:
            for elem2 in elem:
                yield elem2
        else:
            yield elem