python中多个列表的串联

Concatenation of many lists in Python

本问题已经有最佳答案,请猛点这里访问。

假设我有这样一个函数:

1
def getNeighbors(vertex)

返回与给定顶点相邻的顶点列表。现在我想创建一个列表,列出所有邻居的邻居。我是这样做的:

1
2
3
listOfNeighborsNeighbors = []
for neighborVertex in getNeighbors(vertex):
    listOfNeighborsNeighbors.append(getNeighbors(neighborsVertex))

有没有比这更像Python的方法?


通常的解决方案,itertools模块包含:

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

>>> l2=[4, 5, 6]

>>> l3=[7, 8, 9]

>>> import itertools

>>> list(itertools.chain(l1, l2, l3))
[1, 2, 3, 4, 5, 6, 7, 8, 9]


appending列表可以完成与+和sum():

1
2
3
>>> c = [[1, 2], [3, 4]]
>>> sum(c, [])
[1, 2, 3, 4]


1
[x for n in getNeighbors(vertex) for x in getNeighbors(n)]

1
sum(getNeighbors(n) for n in getNeighbors(vertex), [])


如果速度的问题,它可能是更好的使用这个:

1
2
from operator import iadd
reduce(iadd, (getNeighbors(n) for n in getNeighbors(vertex)))

本代码是在该点的列表在列表list.extendconcatenating全由一对一个项目的理解会增加,如果list.append调用。saves位是架空的,制作前(根据我的测量约三倍)的速度。(通常是书面的+=iadd算子和不相同的东西的list.extend)。

使用列表(第一液)comprehensions Ignacio)仍然是正确的,它是通常的方式,更容易阅读。

但绝对避免使用sum(..., []),因为它运行在二次。这是非常impractical列表是很多(超过百或OS)。


采用高速类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
list_of_lists = [[x,1] for x in xrange(1000)]

%timeit list(itertools.chain(*list_of_lists))
100000 loops, best of 3: 14.6 μs per loop

%timeit list(itertools.chain.from_iterable(list_of_lists))
10000 loops, best of 3: 60.2 μs per loop

min(timeit.repeat("ll=[];
for l in list_of_lists:
 ll.extend(l)"
,"list_of_lists=[[x,1] for x in xrange(1000)]",repeat=3, number=100))/100.0
9.620904922485351e-05

%timeit [y for z in list_of_lists for y in z]
10000 loops, best of 3: 108 μs per loop

%timeit sum(list_of_lists, [])
100 loops, best of 3: 3.7 ms per loop


我喜欢,因为它运行在itertools.chain方法(线性和二次(……)中的时间),但"约翰不展示如何处理的动态列表的长度。这里是一个解决方案是打开的。

1
2
import itertools
list(itertools.chain(*[getNeighbors(n) for n in getNeighbors(vertex)]))

你可以摆脱list(...)呼叫,如果你是足够的迭代变量。


利用.extend(更新)(就地)结合而减少(新对象)和(每个小组)应更有效,但是我太懒,:)试验

1
2
mylist = [[1,2], [3,4], [5,6]]
reduce(lambda acc_l, sl: acc_l.extend(sl) or acc_l, mylist)