0

I finally understood why modifying and iterating list will lead to strange results thanks to the answer here: Logic. I have a code that removes duplicates from a list and of course it will return a strange answer.

numbers = [1, 3, 5, 7, 5, 3, 5, 9, 5, 6, 5, 9]

for number in numbers:
    if numbers.count(number) > 1:
        numbers.remove(number)
print(numbers)

To test if I understood the logic, I applied it to try manually derive the strange answer and see if it matched with the computer-generated one.

By senderle's logic I think I should get [1, 5, 7, 3, 9, 6, 9], but the computer answer is [1, 7, 3, 9, 6, 5, 9]. PythonTutor showed that the loop moves to 7, before jumping back to the first 5 which the loop skipped earlier. How is this possible?


My logic: The first time through the loop, 1 is not removed from the list. Then the for loop goes to the second item: 3. Since 3 has a duplicate, it is removed. The loop then goes to the third item, which is 7, not 5! 7 is not removed as it has no duplicates. BUT, here the code jumps back to the 5 it ignored earlier and removes it. Perhaps it's easier to visualize like so, with a ^ pointing to the value :

[1, 3, 5, 7, 5, 3,...]
 ^

That's the state of the list initially; then 1 is not removed and the loop goes to the second item:

[1, 3, 5, 7, 5, 3,...]
    ^

3 is removed and the loop goes to the third item:

[1, 5, 7, 5, 3,...]
       ^

By right, the code should have moved on and thus resulted in a list that has the first 5 (before 7), but instead it gives [1, 7, 3, 9, 6, 5, 9]. Why?

BSMP
  • 4,596
  • 8
  • 33
  • 44
toothpick
  • 125
  • 1
  • 7

2 Answers2

0

The reason is because of how remove works. It removes the first match in a list. You are correct about how the iteration goes, but when the iteration moves to the 5 at index 3 (the second 5 in numbers), it finds that there are duplicates so it removes the first 5 in numbers, which is the one at index 1, not the one at index 3.

To illustrate, after the first 3 is removed, you have this list:

[1, 5, 7, 5, 3, 5, 9, 5, 6, 5, 9]

We find that the bolded 5 has duplicates, but the 5 at index 1 in this list gets removed, not bolded one as the bolded one is not the first 5 in numbers.

Kraigolas
  • 5,121
  • 3
  • 12
  • 37
0

In python list, item gets removed from the beginning of list


[1, 5, 7, 5, 3, 5, 9, 5, 6, 5, 9]
[1, 7, 5, 3, 5, 9, 5, 6, 5, 9]
[1, 7, 3, 5, 9, 5, 6, 5, 9]
[1, 7, 3, 9, 5, 6, 5, 9]
[1, 7, 3, 9, 6, 5, 9]
[1, 7, 3, 9, 6, 5, 9]