I wanted to know if is safe ( documented behaviour? ) to delete the domain space of an iterator in execution in Python.
Consider the code:
import os
import sys
sampleSpace = [ x*x for x in range( 7 ) ]
print sampleSpace
for dx in sampleSpace:
print str( dx )
if dx == 1:
del sampleSpace[ 1 ]
del sampleSpace[ 3 ]
elif dx == 25:
del sampleSpace[ -1 ]
print sampleSpace
'sampleSpace' is what I call 'the domain space of an iterator' ( if there is a more appropriate word/phrase, lemme know ).
What I am doing is deleting values from it while the iterator 'dx' is running through it.
Here is what I expect from the code :
Iteration versus element being pointed to (*):
0: [*0, 1, 4, 9, 16, 25, 36]
1: [0, *1, 4, 9, 16, 25, 36] ( delete 2nd and 5th element after this iteration )
2: [0, 4, *9, 25, 36]
3: [0, 4, 9, *25, 36] ( delete -1th element after this iteration )
4: [0, 4, 9, 25*] ( as the iterator points to nothing/end of list, the loop terminates )
.. and here is what I get:
[0, 1, 4, 9, 16, 25, 36]
0
1
9
25
[0, 4, 9, 25]
As you can see - what I expect is what I get - which is contrary to the behaviour I have had from other languages in such a scenario.
Hence - I wanted to ask you if there is some rule like "the iterator becomes invalid if you mutate its space during iteration" in Python?
Is it safe ( documented behaviour? ) in Python to do stuff like this?
From the Python tutorial:
It is not safe to modify the sequence being iterated over in the loop (this can only happen for mutable sequence types, such as lists). If you need to modify the list you are iterating over (for example, to duplicate selected items) you must iterate over a copy. The slice notation makes this particularly convenient:
>>> for x in a[:]: # make a slice copy of the entire list ... if len(x) > 6: a.insert(0, x) ... >>> a ['defenestrate', 'cat', 'window', 'defenestrate']