如何从列表列表中创建平面列表?
2022-09-05 00:44:15
我想扁平化这个列表列表:
[[1, 2, 3], [4, 5, 6], [7], [8, 9]]
到:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
我想扁平化这个列表列表:
[[1, 2, 3], [4, 5, 6], [7], [8, 9]]
到:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
给定一个列表列表,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 的总和(不计),即 。+
sum
O(L**2)
I * (L**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