基础对象更改时的Python迭代器

标签 python iterator

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

使用一个简单的可变列表,这似乎很明显:迭代器将尝试跟随下一个元素(如果有),如果到达末尾则发送 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

到目前为止,这是不言自明的。我不明白的是,如果我追加一个新元素,迭代器仍将返回 StopIteration

>>> l.append(11)
>>> 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

这在幕后是如何工作的,更复杂的可变可迭代对象的预期行为是什么? (例如,考虑一个表示图形的对象,然后可以使用遍历算法对其进行迭代。如果在迭代时添加/删除节点,应该发生什么?)

最佳答案

PEP 234 中有关于该特定问题的评论(迭代器):

Once a particular iterator object has raised StopIteration, will it also raise StopIteration on all subsequent next() calls?

Some say that it would be useful to require this, others say that it is useful to leave this open to individual iterators. Note that this may require an additional state bit for some iterator implementations (e.g. function-wrapping iterators).

Resolution: once StopIteration is raised, calling it.next() continues to raise StopIteration.

Note: this was in fact not implemented in Python 2.2; there are many cases where an iterator's next() method can raise StopIteration on one call but not on the next. This has been remedied in Python 2.3.

关于基础对象更改时的Python迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22987320/

相关文章:

python - imap函数: passing a list and a another fixed string as argument (Python 3. 7/3.8)

rust - 如何使用以迭代器为参数的方法进行动态调度?

c++ - 双向迭代容器

python - 嵌套迭代器上的 islice

python - 关闭请求库中的代理

python - 统计文件中单词的出现次数

python - 在没有命令行工具 (fab) 的情况下使用 Python Fabric

python - 重新加载 django 模型以处理单元测试中的 @override_settings

iterator - Iterator collect 的类型问题

C++ 双向迭代器前缀递增