【问题标题】:Re-using zip iterator in python 3 [duplicate]在python 3中重新使用zip迭代器[重复]
【发布时间】:2018-11-01 02:53:54
【问题描述】:

我有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)))

【问题讨论】:

标签: python python-3.x iterator


【解决方案1】:

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

避免它的最简单方法是:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 对于任意数量的变量,您将使用字典而不是许多命名变量。但你的其余答案是有道理的。
      • 好点@jpp
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-01
      • 2020-01-01
      • 2017-02-12
      • 2014-12-12
      • 2015-10-19
      相关资源
      最近更新 更多