Bridgo
Bridgo

Reputation: 149

List "quirk" in python

I was trying out some things with lists in the interactive interpreter and I noticed this:

>>> list = range(1, 11)
>>> for i in list:
...     list.remove(i)
...
>>> list
[2, 4, 6, 8, 10]

Can anyone explain why it left even numbers? This is confusing me right now... Thanks a lot.

Upvotes: 4

Views: 262

Answers (4)

johnsyweb
johnsyweb

Reputation: 141810

I find this easiest to explain using Python:

>>> for iteration, i in enumerate(lst):
...     print 'Begin iteration', iteration, 'where lst =', str(lst), 'and the value at index', iteration, 'is', lst[iteration]
...     lst.remove(i)
...     print 'End iteration', iteration, 'where lst =', str(lst), 'with', i, 'removed\n'
... 
Begin iteration 0 where lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and the value at index 0 is 1
End iteration 0 where lst = [2, 3, 4, 5, 6, 7, 8, 9, 10] with 1 removed

Begin iteration 1 where lst = [2, 3, 4, 5, 6, 7, 8, 9, 10] and the value at index 1 is 3
End iteration 1 where lst = [2, 4, 5, 6, 7, 8, 9, 10] with 3 removed

Begin iteration 2 where lst = [2, 4, 5, 6, 7, 8, 9, 10] and the value at index 2 is 5
End iteration 2 where lst = [2, 4, 6, 7, 8, 9, 10] with 5 removed

Begin iteration 3 where lst = [2, 4, 6, 7, 8, 9, 10] and the value at index 3 is 7
End iteration 3 where lst = [2, 4, 6, 8, 9, 10] with 7 removed

Begin iteration 4 where lst = [2, 4, 6, 8, 9, 10] and the value at index 4 is 9
End iteration 4 where lst = [2, 4, 6, 8, 10] with 9 removed

Note that it's a bad idea to (a) modify a list while iterating over it and (b) call a list "list".

Upvotes: 2

ekhumoro
ekhumoro

Reputation: 120608

If you want to modify a list whilst iterating over it, work from back to front:

lst = range(1, 11)
for i in reversed(lst):
    lst.remove(i)

Upvotes: 3

Owen
Owen

Reputation: 39366

My guess is that the for loop is implemented like the following:

list = range(1, 11)

i = 0
while i < len(list):
    list.remove(list[i])
    i += 1

print(list)

Every time an element is removed, the "next" element slides into its spot, but i gets incremented anyway, skipping 2 elements.

But yes, ObscureRobot is right, it's not really safe to do this (and this is probably undefined behavior).

Upvotes: 4

ObscureRobot
ObscureRobot

Reputation: 7336

It isn't safe to modify a list that you are iterating over.

Upvotes: 7

Related Questions