1

I was working on a list and I noticed something.

For example, this piece of code is deleting odd numbers from a list while looping over it.

numbers=[x for x in range (100)]
for nb in numbers:
    if nb%2 == 1:
        del numbers[numbers.index(nb)]

When you add a counter to see the total iterations you get:

numbers=[x for x in range (100)]
counter=0
for nb in numbers:
    if nb%2 == 1:
        del numbers[numbers.index(nb)]
    counter +=1

The result is counter = 51.

However, if you add the operator list() on the for loop:

numbers=[x for x in range (100)]
counter=0
for nb in list(numbers):
    if nb%2 == 1:
        del numbers[numbers.index(nb)]
    counter +=1

This time the result is counter = 100.

I would like to know why and what is the role of the operator list() here.

Note: if you print numbers and list(numbers) they are identical.

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
M1LL1X
  • 13
  • 2
  • 3
    Does this answer your question? [How to remove items from a list while iterating?](https://stackoverflow.com/questions/1207406/how-to-remove-items-from-a-list-while-iterating) – Woodford Jul 23 '21 at 22:34
  • 2
    In the first case, you are modifying the list as you iterate over it, which is bad practice and leads to the odd behavior you've observed. In the second case, you are iterating over a copy of the list and then modifying the original list. This is fine and produces the result you expect. – Craig Jul 23 '21 at 22:35

1 Answers1

0

Your second example makes a copy of the list. You iterate through that copy, which remains at 100 elements regardless of what you do to numbers in the meantime.

Your first example alters the list as you iterate through it, a well-documented and well-know bad idea. If you print the list and current value of nb on each iteration, you'll see how the progression works. A simplistic view is that the Python interpreter walks through the list by index (position); when you shorten the list, everything shifts down one position, but that index still increments, thus skipping over one item.

Prune
  • 76,765
  • 14
  • 60
  • 81