是否有从 Python 中的列表列表中制作简单列表的快捷方式?
我可以for循环进行,但是有没有一些很酷的“单线”?
for
我试过functools.reduce():
functools.reduce()
from functools import reduce l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] reduce(lambda x, y: x.extend(y), l)
但我收到此错误:
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 1, in <lambda> AttributeError: 'NoneType' object has no attribute 'extend'
给定一个列表列表t,
t
flat_list = [item for sublist in t for item in sublist]
意思是:
flat_list = [] for sublist in t: for item in sublist: flat_list.append(item)
比迄今为止发布的快捷方式更快。(t是要展平的列表。)
下面是对应的函数:
def flatten(t): return [item for sublist in t for item in sublist]
作为证据,您可以使用timeit标准库中的模块:
timeit
$ python -mtimeit -s't=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in t for item in sublist]' 10000 loops, best of 3: 143 usec per loop $ python -mtimeit -s't=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(t, [])' 1000 loops, best of 3: 969 usec per loop $ python -mtimeit -s't=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,t)' 1000 loops, best of 3: 1.1 msec per loop
说明:基于+(包括 in 的隐含使用sum)的快捷方式是,O(T**2)当有 T 个子列表时——随着中间结果列表越来越长,每一步都会分配一个新的中间结果列表对象,并且所有项目必须复制之前的中间结果(以及最后添加的一些新结果)。因此,为简单起见且不失一般性,假设每个子列表都有 k 个项目:前 k 个项目来回复制 T-1 次,后 k 个项目 T-2 次,依此类推;对于从 1 到 T 排除的 x,副本总数是 x 总和的 k 倍,即k * (T**2)/2。
+
sum
O(T**2)
k * (T**2)/2
列表推导式只生成一个列表,一次,并将每个项目(从其原始居住地到结果列表)复制一次。