在 python 3 中重用 zip 迭代器



我有zip对象:

L_RANGES = zip(range(10, 20), range(11, 21))

第一次调用L_RANGES是可以的:

print(type(L_RANGES))
for a, b in L_RANGES:
print(a, b)

输出:

<class 'zip'>
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 19
19 20

Bu 下一个调用不显示任何内容。有没有办法维护或重置它。到目前为止,我可以将其转换为列表:

L_RANGES = list(zip(range(10, 20), range(11, 21)))

如果你每次循环时都要创建一个生成器,这将解决所有问题,因为你可以多次重用它。为此,将L_RANGES从简单的生成器转换为创建生成器lambda,但不要忘记每次都使用()"调用"它:

L_RANGES = lambda: zip(range(10, 20), range(11, 21))
for a, b in L_RANGES():
print(a, b)
for a, b in L_RANGES():
print(a, b)
#works as many times as you want

与其他答案相比,这不会占用内存(这是转换为列表的缺点(,并且每次要循环时都不需要多个变量(通过使用tee(,这使得这种方式更加灵活(如有必要,您可以迭代 1000 次,而无需创建L_RANGES_1...L_RANGES_999(,例如:

for i in range(1000):
for a, b in L_RANGES():
print(a, b)

迭代器一旦用尽,就不能重复使用。在Python 3.x中,zip返回一个迭代器。一种解决方案是使用itertools.tee复制迭代器n次。

例如, 设置n = 2,我们可以执行以下操作:

from itertools import tee
L_RANGES_1, L_RANGES_2 = tee(zip(range(10, 20), range(11, 21)), 2)
for item in L_RANGES_1:
# do something
for item in L_RANGES_2:
# do something else

转换为list允许使用任意次数,但由于内存开销,不建议用于大型可迭代对象。

对于大量副本,您可以使用字典。例如:

L_RANGES = dict(zip(range(1000), tee(zip(range(10, 20), range(11, 21)), 1000)))

在 Python 3.x 中,zip()返回耗尽的迭代器。

避免它的最简单方法是:

L_RANGES = list(zip(range(10, 20), range(11, 21)))

最新更新