在python 3中重用zip迭代器[复制]

xmjla07d  于 2023-01-08  发布在  Python
关注(0)|答案(3)|浏览(149)
    • 此问题在此处已有答案**:

Why can't I iterate twice over the same iterator? How can I "reset" the iterator or reuse the data?(5个答案)
四年前关闭了。
我有一个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

但是接下来的调用没有显示任何内容。有什么方法可以维护或重置它吗?到目前为止,我可以将它转换为列表:

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

ymdaylpp1#

如果每次循环都创建一个生成器,那么一切问题都解决了,因为你可以多次重用它,为此,将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)
jmp7cifd

jmp7cifd2#

迭代器一旦耗尽,就不能重用,在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)))
6rqinv9w

6rqinv9w3#

在Python 3.x中,zip()返回耗尽的迭代器。
最简单的避免方法是:

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

相关问题