Why List mutation is not a good idea while iterating over the same list.

What happens when you mutate the list while iterating over it?

Lets define a list having 10 values..

>>> l = range(10)
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Lets see what happens if you mutate the list while iterating over it…

>>> for i in l:
...     if i == 3:
...         l.remove(3)
...     if i == 4:
...         l.remove(4)
... 
>>> l
[0, 1, 2, 4, 5, 6, 7, 8, 9]

As per the logic it should remove 3, 4 values when they match with i while iterating.And ideally one would expect to see this [0, 1, 2, 5, 6, 7, 8, 9] out put.

But in the above output still having value 4 in the list even though you’ve removed it when ` if i == 4: l.remove(4)`.

So the reason for 4 not being deleted here is.. When you’ve removed value 3 from the list where if i == 3: l.remove(3) (here the index of value 3 is 3) list gets shrinked to [0, 1, 2, 4, 5, 6, 7, 8, 9] and still the iterator holds the index 3 and after shrinking the l[3] is 4, and for next iteration when index ++ happens the new index hold by next() becomes 4 but after shrinking the value at l[4] is 5, for this reason it never checks the ` i == 4`.

So never mutate the mutable objects while iterating over it.

Published: July 26 2015

  • category:
blog comments powered by Disqus