I would like to know what's the general behaviour of an iterator if the underlaying object changes during the iteration.
Using a simple mutable list, it seems obvious: the iterator will try to follow on the next element if any, and send StopIteration if the end is reached.
>>> 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
This is self-explanatory so far. What I don't understand is, that if I append a new element, the iterator will still return StopIteration.
>>> l.append(11)
>>> a.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
If I do the same before reaching the end:
>>> l=[1]
>>> a=iter(l)
>>> a.next()
1
>>> l.append(2)
>>> a.next()
2
How is this working under the hood, and what is the expected behaviour of a more complex mutable iterable object? (e.g. think of an object representing a graph, which then can be iterated over, using a traversal algorithm. What is supposed to happen then if nodes are added/removed while iterating?)
There's a comment on that particular issue in PEP 234 (Iterators):
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With