如果子列表长度相同,则展平列表

时间:2015-01-04 14:06:07

标签: python python-2.7 flatten

我有一个列表,例如[[1,2], [3,4], [5,6], [7,8], [9,10]]。我想得到[1,2,3,4,5,6,7,8,9,10]

This question为一般的展平列表提供了一些非常好的选项。这里给出的答案适用于可变长度子列表。但是,我知道每个子列表具有相同的长度(特别是长度为2)。

我想知道是否有可能利用同质子列表长度来改进我链接的问题中给出的答案。特别是,在展开此列表时,有什么能比[item for sublist in l for item in sublist]更好吗?

编辑:更好的',对于很长的列表,我的意思更快。

编辑:

有一点我没有提及 - 我不关心扁平化列表的顺序(但我关心多重性)

import timeit
import itertools
def f0():
    l=[[1,2]]*99
    [item for sublist in l for item in sublist]
def f1():
    l=[[1,2]]*99
    list(itertools.chain.from_iterable(l))
def f2():
    l = [[1,2]]*99
    z = map(list,zip(*l))
    z[0].extend(z[1])

print timeit.timeit("f0()", setup="from __main__ import f0, f1, f2", number=10000)
print timeit.timeit("f1()", setup="from __main__ import f0, f1, f2", number=10000)
print timeit.timeit("f2()", setup="from __main__ import f0, f1, f2", number=10000)

产生输出

0.13874912262
0.103307008743
0.10813999176

我的zip功能可以更快完成吗?

2 个答案:

答案 0 :(得分:3)

一点时间表明列表理解比itertools版本略快(对于短列表 - Hackaholic's answer表明长列表的反面是正确的):

>>> import timeit
>>> timeit.timeit("[item for sublist in a for item in sublist]", 
                  setup="import itertools; a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]")
1.7200839519500732
>>> timeit.timeit("list(itertools.chain.from_iterable(a))", 
                  setup="import itertools; a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]")
2.0097079277038574

如果您可以避免构建整个列表,迭代chain.from_iterable的输出而不是将其传递给list构造函数,那么迭代方法的关键优势就来了。

如果您正在对阵列进行操作并且性能是一个关键考虑因素,请考虑使用numpy,虽然不是标准库的一部分,但很多更快(一旦你拥有了阵列):

>>> import numpy as np
>>> a = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])
>>> a
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [ 7,  8],
       [ 9, 10]])
>>> a.ravel()
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
>>> timeit.timeit("a.ravel()",
                  setup="import numpy as np; a = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])")
0.36390113830566406

答案 1 :(得分:2)

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

输出:

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

现在比较时间:小名单

>>> timeit.timeit("list(itertools.chain.from_iterable(a))",setup='import itertools;a = [[1,2], [3,4], [5,6], [7,8], [9,10]]') 
0.9853601455688477
>>> timeit.timeit("[ y for x in a for y in x]",setup='a = [[1,2], [3,4], [5,6], [7,8], [9,10]]') 
0.9124641418457031

对于大型列表:

以下是优选迭代器的结果:

>>> timeit.timeit("list(itertools.chain.from_iterable(a))",setup='import itertools;a = zip(range(100),range(100))',number=1000000) 
8.213459014892578
>>> timeit.timeit("[ y for x in a for y in x]",setup='a=zip(range(100),range(100))',number=1000000) 
12.833590984344482

从小列表中list comprehension很好,但是对于大型,您需要使用iterators

相关问题