如何从列表列表中创建平面列表?

我想扁平化这个列表列表:

[[1, 2, 3], [4, 5, 6], [7], [8, 9]]

到:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

答案 1

给定一个列表列表,l

flat_list = [item for sublist in l for item in sublist]

这意味着:

flat_list = []
for sublist in l:
    for item in sublist:
        flat_list.append(item)

比到目前为止发布的快捷方式更快。( 是要平展的列表。l

下面是相应的函数:

def flatten(l):
    return [item for sublist in l for item in sublist]

作为证据,您可以使用标准库中的模块:timeit

$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 3: 143 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'
1000 loops, best of 3: 969 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,l)'
1000 loops, best of 3: 1.1 msec per loop

解释:基于(包括 隐含用法)的快捷方式是必要的,当有L个子列表时 - 随着中间结果列表变得越来越长,在每一步中分配一个新的中间结果列表对象,并且必须复制上一个中间结果中的所有项目(以及最后添加的一些新项目)。因此,为了简单起见,并且在不实际失去通用性的情况下,假设您每个都有I项的L子列表:第一个I项来回复制L-1次,第二个I项L-2次,依此类推;副本总数是 I 乘以 x 对 x 从 1 到 L 的总和(不计),即 。+sumO(L**2)I * (L**2)/2

列表理解只生成一个列表,一次,并将每个项目复制过来(从其原始居住地到结果列表)也恰好一次。


答案 2

你可以使用 itertools.chain()

>>> import itertools
>>> list2d = [[1,2,3], [4,5,6], [7], [8,9]]
>>> merged = list(itertools.chain(*list2d))

或者,您可以使用 itertools.chain.from_iterable(),它不需要使用运算符解压缩列表:*

>>> import itertools
>>> list2d = [[1,2,3], [4,5,6], [7], [8,9]]
>>> merged = list(itertools.chain.from_iterable(list2d))

这种方法可以说比可读性更强,而且似乎也更快:[item for sublist in l for item in sublist]

$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99;import itertools' 'list(itertools.chain.from_iterable(l))'
20000 loops, best of 5: 10.8 usec per loop
$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 5: 21.7 usec per loop
$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'
1000 loops, best of 5: 258 usec per loop
$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99;from functools import reduce' 'reduce(lambda x,y: x+y,l)'
1000 loops, best of 5: 292 usec per loop
$ python3 --version
Python 3.7.5rc1