底层对象更改时的Python迭代器

底层对象更改时的Python迭代器,python,iterator,Python,Iterator,我想知道,如果底层对象在迭代过程中发生变化,迭代器的一般行为是什么 使用一个简单的可变列表,这似乎很明显:迭代器将尝试跟踪下一个元素(如果有),如果到达末尾,则发送StopIteration >>> l = range(10) >>> a = iter(l) >>> a.next() 0 >>> a.next() 1 >>> a.next() 2 >>> l[3]='a' >>

我想知道,如果底层对象在迭代过程中发生变化,迭代器的一般行为是什么

使用一个简单的可变列表,这似乎很明显:迭代器将尝试跟踪下一个元素(如果有),如果到达末尾,则发送
StopIteration

>>> l = range(10)
>>> a = iter(l)
>>> a.next()
0
>>> a.next()
1
>>> a.next()
2
>>> l[3]='a'
>>> a.next()
'a'
>>> a.next()
4
>>> del l[5]
>>> a.next()
6
>>> a.next()
7
>>> a.next()
8
>>> a.next()
9
>>> a.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
如果我在到达终点之前也这样做:

>>> l=[1]
>>> a=iter(l)
>>> a.next()
1
>>> l.append(2)
>>> a.next()
2

这在引擎盖下是如何工作的,更复杂的可变对象的预期行为是什么?(例如,想象一个表示图形的对象,然后可以使用遍历算法对其进行迭代。如果在迭代过程中添加/删除节点,会发生什么?

在(迭代器)中有一个关于该特定问题的注释:

一旦特定迭代器对象引发StopIteration,将 它还会在所有后续的next()调用上引发StopIteration

一些人说,这将是有益的要求,其他人说 让每个迭代器都可以使用它。 请注意,对于某些情况,这可能需要额外的状态位 迭代器实现(例如函数包装迭代器)

解析:一旦提出StopIteration,调用它。next() 继续提升StopIteration

注意:这实际上并没有在Python2.2中实现;有 在许多情况下,迭代器的next()方法可能会引发 在一个调用上停止迭代,但在下一个调用上不停止迭代。这是 在Python 2.3中进行了修正


迭代对象时更改对象有三种典型行为:

  • 新数据将被返回
  • 新数据将被忽略
  • 将跳过旧数据
换句话说:实际行为是未定义的


在迭代对象时更改对象是一个常见的问题,在Python3中,类型
set
dict
(可能还有其他类型)如果在迭代过程中检测到添加或删除,则更改为立即引发错误。

有些迭代器即使在引发
StopIteration
之后也可以生成更多数据;这样的迭代器是


这并不意味着迭代器出了问题——这意味着如果不小心使用这样的迭代器,可能会导致错误和代码中断。

回答:不要这样做。你问在这种情况下会发生什么,但实际上你自己却意外地找到了答案:这种行为通常是不明确的。这是一种建议还是语言强制的?如果我实现了一个迭代器类,我是否需要注意,一旦uu next_uu()返回StopIteration,它就不会返回任何其他内容?不,它不会强制执行。你必须自己实施这种行为。
>>> l=[1]
>>> a=iter(l)
>>> a.next()
1
>>> l.append(2)
>>> a.next()
2