【问题标题】:Is calling next(iter) inside for i in iter supported in python?是否在 python 支持的 iter 中为 i 调用 next(iter)?
【发布时间】:2017-05-25 22:06:13
【问题描述】:

问题:Python list iterator behavior and next(iterator) 记录了调用的事实

for i in iter:
    ...
    next(iter)

具有在 for 循环中向前跳过的效果。这是我可以依赖的已定义行为(例如,在某些 PEP 中)还是仅仅是可能在没有警告的情况下更改的实施意外?

【问题讨论】:

    标签: python for-loop iterator next pep


    【解决方案1】:

    在for循环中,它总是调用迭代项的next

    如果你在for循环调用next之前调用next(),那么它具有跳过(下一个)项目的效果。

    也就是说,你可以在你的程序中实现这个,只要for调用相同的方法(下一个)。

    到目前为止,即使在 3.6 中,也正在执行相同的操作。所以,不用担心。

    【讨论】:

      【解决方案2】:

      这取决于iter 是什么。如果它是一个迭代器,通过调用iter() 在可迭代对象上创建,那么是的,调用next(iter) 也会推进迭代器:

      >>> it = iter(range(4))
      >>> for x in it:
              print(x)
              _ = next(it)
      
      0
      2
      

      重要的是it 是一个迭代器(而不是任何可迭代的),因为for 循环内部也会在该对象上调用iter()。由于迭代器(通常)在调用 iter(some_iterator) 时会返回自身,因此可以正常工作。

      这是个好主意吗?一般不会,因为它很容易坏:

      >>> it = iter(range(3))
      >>> for x in it:
              print(x)
              _ = next(it)
      
      0
      2
      Traceback (most recent call last):
        File "<pyshell#21>", line 3, in <module>
          _ = next(it)
      StopIteration
      

      您必须在循环内手动为StopIteration 异常添加异常处理;这很容易变得一团糟。当然你也可以使用默认值,例如而是next(it, None),但这很快就会变得令人困惑,尤其是当您实际上没有将值用于任何事情时。

      一旦有人后来决定不使用迭代器,而是在 for 循环中使用其他可迭代的对象(例如,因为他们正在重构代码以使用那里的列表,然后一切都中断了),整个概念也会中断。

      您应该尝试让 for 循环成为唯一使用迭代器的循环。更改您的逻辑,以便您可以轻松确定是否应跳过迭代:如果可以,在开始循环之前过滤可迭代的first。否则,使用条件来跳过循环内的迭代(使用continue):

      >>> it = filter(lambda x: x % 2 == 0, range(3))
      >>> for x in it:
              print(x)
      
      0
      2
      
      >>> it = range(3) # no need for an iterator here
      >>> for x in it:
              if x % 2 == 1:
                  continue
              print(x)
      
      0
      2
      

      【讨论】:

      • 在你的例子中 range(0,3,2) 就足够了
      • @Chris_Rands 是的,我不想在这里依赖range() 功能。我的观点是,这些方法适用于任何类型的可迭代对象。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-13
      • 2017-01-05
      • 2020-10-10
      • 2018-11-10
      • 2011-11-08
      • 2020-10-14
      • 2020-02-22
      相关资源
      最近更新 更多