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

flattening list if sublists are same length

我有一个列表,例如 [[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] 更能使这个列表变平?

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

编辑:

有一件事我没有提到——我不关心扁平化列表的顺序(但我关心多重性)

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 功能可以更快地完成吗?

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

一点时间表明列表理解比 itertools 版本稍快(对于短列表 - 表明长列表的情况正好相反):

>>> 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