我发现最快的是从一个空数组开始并扩展它:
In [1]: a = [['abc', 'def'], ['ghi'],['xzy']]
In [2]: result = []
In [3]: extend = result.extend
In [4]: for l in a:
...: extend(l)
...:
In [5]: result
Out[5]: ['abc', 'def', 'ghi', 'xzy']
这比 Alex Martelli 尝试中的示例快两倍多:Making a flat list out of lists in Python
$ 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: 86.3 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'b = []' 'extend = b.extend' 'for sub in l:' ' extend(sub)'
10000 loops, best of 3: 36.6 usec per loop
我想出这个是因为我有一种预感,在幕后,extend 会为列表分配适量的内存,并且可能使用一些低级代码来移动项目。我不知道这是否属实,但是谁在乎,它更快。
顺便说一句,这只是线性加速:
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]' 'b = []' 'extend = b.extend' 'for sub in l:' ' extend(sub)'
1000000 loops, best of 3: 0.844 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]' '[item for sublist in l for item in sublist]'
1000000 loops, best of 3: 1.56 usec per loop
您也可以使用map(results.extend, a)
,但这会比较慢,因为它正在构建自己的 None 列表。
它还为您提供了一些不使用函数式编程的好处。IE
- 您可以扩展现有列表而不是创建一个空列表,
- 你仍然可以一眼看懂代码,几分钟、几天甚至几个月后。
顺便说一句,最好避免列表推导。小的还不错,但一般来说,列表推导式实际上并不能为您节省很多打字时间,但通常更难理解,也很难更改或重构(见过三级列表推导式吗?)。谷歌编码指南建议不要使用它们,除非在简单的情况下。我的观点是它们只在“丢弃”代码中有用,即作者不关心可读性的代码,或者已知永远不需要将来维护的代码。
比较这两种写同一件事的方式:
result = [item for sublist in l for item in sublist]
有了这个:
result = []
for sublist in l:
for item in sublist:
result.append(item)
YMMV,但第一个让我停下了脚步,我不得不考虑一下。在第二个中,从缩进中可以明显看出嵌套。