When can/can't you modify a list during iteration?

57 views Asked by At

You are not supposed to modify a list during iteration apparently. I can see the potential for problems, but I'm not sure when it is or isn't OK. For example, the code below seems to work fine:

import random

xs = [random.randint(-9,9) for _ in range(5)]
print(xs, sum(xs))
xs = [x * -1 for x in xs]
print(xs, sum(xs))

Is this OK because the list comprehension works differently to a normal for loop?

This version seems equally unproblematic:

import random

xs = [random.randint(-9,9) for _ in range(5)]
print(xs, sum(xs))

for i in range(len(xs)):
    xs[i] *= -1
    
print(xs, sum(xs))

So it looks like for this kind of use case there is no issue, unless I'm missing something.

What then are the situations when it is or isn't OK to modify a list while iterating over it?

2

There are 2 answers

0
Lecdi On

List comprehensions are always fine because you are creating a new list from the one you are iterating over, not modifying the one you are iterating over.

It is also ok to modify a list in a for loop, as long as you don't add/remove any elements.

The problem comes when you add elements to / remove elements from a list. This causes the length of the list to change, so the for loop doesn't know when to end.

The for loop will always try to run to the original length of the list, which will cause an index error if you have shortened the list.

If you have made the list longer, then the for loop will not go to all of the elements in the list.

0
manoj On

Run the below code and you will see the difference. in you case you are precomputing the len probably thus change in the list is immeterial

import random

xs = [random.randint(-9,9) for _ in range(5)]
print(xs, sum(xs))

[-7, 9, 2, 4, -9] -1


print(xs)

N = len(xs)

for i, val in enumerate(xs):
    print(val)
    xs[N-i-1] *= -1
    
print(xs, sum(xs))


[7, -9, -2, -4, 9] 1