Python中许多列表的连接

时间:2010-06-11 09:22:55

标签: python list concatenation

假设我有这样的功能:

def getNeighbors(vertex)

返回给定顶点的邻居顶点列表。现在我想创建一个包含邻居所有邻居的列表。我这样做:

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

有更多的pythonic方式吗?

7 个答案:

答案 0 :(得分:45)

像往常一样,itertools模块包含一个解决方案:

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

答案 1 :(得分:32)

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

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

答案 2 :(得分:32)

附加列表可以使用+和sum()完成:

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

答案 3 :(得分:12)

如果速度很重要,最好使用它:

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

此代码的重点是按list.extend连接整个列表,其中列表理解会逐个添加一个项目,就像调用list.append一样。这节省了一些开销,使前者(根据我的测量)大约快三倍。 (iadd运算符通常写为+=,与list.extend执行相同的操作。)

使用列表推导(Ignacio的第一个解决方案)通常仍然是正确的方式,它更容易阅读。

但绝对避免使用sum(..., []),因为它以二次方运行。对于许多列表(超过一百个左右)来说,这是非常不切实际的。

答案 4 :(得分:9)

按速度排序:

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=[];\nfor l in list_of_lists:\n 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

答案 5 :(得分:2)

我喜欢itertools.chain方法,因为它以线性时间运行(sum(...)以qudratic时间运行)但@Jochen没有显示如何处理动态长度列表。这是OP问题的解决方案。

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

如果可迭代就足以让你摆脱list(...)电话。

答案 6 :(得分:0)

使用 .extend()(就地更新)与reduce结合而不是 sum()(每次都是新对象)应该更高效但是我也是懒得测试:)

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