Removing from a list while iterating over it

Viewed 5250

The following code:

a = list(range(10))
remove = False
for b in a:
    if remove:
        a.remove(b)
    remove = not remove
print(a)

Outputs [0, 2, 3, 5, 6, 8, 9], instead of [0, 2, 4, 6, 8] when using Python 3.2.

  1. Why does it output these particular values?
  2. Why is no error given to indicate that underlying iterator is being modified?
  3. Have the mechanics changed from earlier versions of Python with respect to this behaviour?

Note that I am not looking to work around the behaviour, but to understand it.

5 Answers

If you add a reversed() to the for loop, you can traverse the array backwards, while removing items and get the expected output. Element position with an array depends on the preceding elements not the following elements:

Therefore the code:

a = list(range(10))
remove = True
for b in reversed(a):
    if remove:
        a.remove(b)
    remove = not remove
print(a)

produces the expected: [0, 2, 4, 6, 8]

Related