Python 为什么对iterable调用list()会改变它?
考虑一下这个代码,其中我使用了Python 为什么对iterable调用list()会改变它?,python,iterator,iterable,Python,Iterator,Iterable,考虑一下这个代码,其中我使用了组合,并尝试将它们列成一个列表 from itertools import combinations t = (1,2,3,4) print("t is %r" % (t,)) print("list(t) is %r" % list(t)) print("list(t) is %r" % list(t)) t2 = ("a", "b", "c", "d") print("t2 is %r" % (t2,)) combs = combinations(t2,
组合
,并尝试将它们列成一个列表
from itertools import combinations
t = (1,2,3,4)
print("t is %r" % (t,))
print("list(t) is %r" % list(t))
print("list(t) is %r" % list(t))
t2 = ("a", "b", "c", "d")
print("t2 is %r" % (t2,))
combs = combinations(t2, 2)
print("List of combinations of t2: %r" % list(combs))
print("List of combinations of t2: %r" % list(combs))
输出是(对我来说出乎意料)
显然,list()
有副作用。
正如预期的那样,将元组转换为列表不会改变原始数据,我可以多次这样做。但是当我尝试使用从组合返回的iterable时,这只起作用一次,然后iterable似乎无效。list
是否在iterable上调用next
,以便在完成后迭代器位于末尾,或者为什么会发生这种情况?
如何避免它呢?itertools.compositions
生成一个惰性生成器,而不是保存在内存中的完整数据结构。一旦你用类似于list()
的东西将其耗尽(遍历),它就是。。。嗯,累坏了。空的。如果要重复使用,请保存引用:
combs = list(combinations(t2, 2))
print("List of combinations of t2: %r" % combs)
print("List of combinations of t2: %r" % combs)
正如您正确观察到的,列表
具有破坏性,因为发电机只能耗尽一次。一个简单的解决方案是使用:
这可能比保留整个列表更节省内存,因为itertools.tee
只需要保留尚未被所有迭代器使用的元素。combines
是一个生成器函数,您只能迭代一次。在它上面调用列表
会耗尽它。。。
combs = list(combinations(t2, 2))
print("List of combinations of t2: %r" % combs)
print("List of combinations of t2: %r" % combs)
>>> c1, c2 = itertools.tee(itertools.combinations(["a", "b", "c"], 2))
>>> print(list(c1))
... will print the entire sequence of combinations
>>> print(list(c2))
... same as before