假设我有这样的功能:
def getNeighbors(vertex)
返回给定顶点的邻居顶点列表。现在我想创建一个包含邻居所有邻居的列表。我这样做:
listOfNeighborsNeighbors = []
for neighborVertex in getNeighbors(vertex):
listOfNeighborsNeighbors.append(getNeighbors(neighborsVertex))
有更多的pythonic方式吗?
答案 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)