Code:
arr = [ i for i in xrange(10) ]
for i in arr:
if i in arr:
print i
arr.pop(0)
print arr
And the output:
$ python2.7 ts.py
0
2
4
6
8
[5, 6, 7, 8, 9]
Why is this the result? Shouldn't it be []
?
Code:
arr = [ i for i in xrange(10) ]
for i in arr:
if i in arr:
print i
arr.pop(0)
print arr
And the output:
$ python2.7 ts.py
0
2
4
6
8
[5, 6, 7, 8, 9]
Why is this the result? Shouldn't it be []
?
Let me show you what happens in the code:
Let's see how does it work under the hood. Firstly, we need an iterator:
And we will call
next(it)
until it rises aStopIteration
exception. So, let's do it:Wow, we got the first element from the list! Let's see, what will happen if we try to pop element with zero index:
Okay, element has popped. Move to next loop iteration:
Hmm... Seems right, we got the second element. Let's pop the first again!
Let's see at third iteration:
I guess, it's clear now, that loop will have 5 iterations. In each iteration you will remove the first element. And, because of it, you will skip odd elements while iterating.
It is not recommended to modify the sequence(or mapping) while you iterate it. It will mess interal pointer.
For example, following code will never end.
According to
for
statement - NOTE:Apparently what you whanted is:
Because, as @falsetru mentioned, changing the sequence during the iteration is not recommended, but in this example your for loop is based on a constant value, i.e. the length of
arr
. Eachpop()
will remove the first element and the list will be progressively emptied.Updating a Sequence while Iterating has some unexpected results, which is why it is never recommended. The following graphic depicts how the variable
i
changes every time you iterate while popping from the listIt's easier to see whats going on by adding an enumerate:
outputs:
Popping changes the length of the array but the index for the iterator isn't updated to reflect this.