在python 3中重用zip迭代器

tor*_*eff 2 python iterator python-3.x

我有一个zip对象:

L_RANGES = zip(range(10, 20), range(11, 21))
Run Code Online (Sandbox Code Playgroud)

第一次打电话L_RANGES是好的:

print(type(L_RANGES))
for a, b in L_RANGES:
  print(a, b)
Run Code Online (Sandbox Code Playgroud)

输出:

<class 'zip'>
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 19
19 20
Run Code Online (Sandbox Code Playgroud)

接下来的电话不显示任何内容.有没有办法维护或重置它.到目前为止,我可以将其转换为列表:

L_RANGES = list(zip(range(10, 20), range(11, 21)))
Run Code Online (Sandbox Code Playgroud)

Ofe*_*dan 8

如果您每次循环时都创建一个生成器,那将解决所有问题,因为您可以多次重复使用它。为此,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
Run Code Online (Sandbox Code Playgroud)

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

for i in range(1000):
    for a, b in L_RANGES():
        print(a, b)
Run Code Online (Sandbox Code Playgroud)


jpp*_*jpp 5

迭代器一旦耗尽,可能无法重用.在Python 3.x中,zip返回一个迭代器.一种解决方案是使用nitertools.tee复制迭代器.

例如,设置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
Run Code Online (Sandbox Code Playgroud)

转换为a list允许使用任意次数,但由于内存开销,不适用于大型迭代.

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

L_RANGES = dict(zip(range(1000), tee(zip(range(10, 20), range(11, 21)), 1000)))
Run Code Online (Sandbox Code Playgroud)