0

Question: Python list iterator behavior and next(iterator) documents the fact that calling

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

Has the effect of skipping ahead in the for loop. Is this defined behavior that I can rely on (e.g. in some PEP) or merely an accident of implementation that could change without warning?

4

2 回答 2

3

这取决于是什么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 循环成为唯一使用迭代器的循环。更改您的逻辑,以便您可以轻松确定是否应跳过迭代:如果可以,请先过滤可迭代对象然后再开始循环。否则,使用条件来跳过循环内的迭代(使用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
于 2017-01-11T08:07:29.153 回答
1

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

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

所以,话虽这么说,你可以在你的程序中实现它,只要for调用相同的方法(下一个)。

到目前为止,即使在3.6相同的情况下正在实施。所以,没有必要担心。

于 2017-01-11T07:55:53.763 回答