0

I wrote an algorithm that shall print a number in a sequence that is NOT redundant.

My algo:

o = [2,3,4,5,2,4,5]
for x in o:
  print(x)
  o.remove(x)
  if x not in o:
    print("NOT REDUNDANT" + str(x))

out:

2
4
2
NOT REDUNDANT 2
5

Where the heck is the output of the 3 at index two of the list?

If I add an o.sort() right under the initialization of o I get the correct output:

o = [2,3,4,5,2,4,5]
o.sort()
for x in o:
  print(x)
  o.remove(x)
  if x not in o:
    print("NOT REDUNDANT" + str(x))

out:

2
3
NOT REDUNDANT 3
4
5

Can someone explain why the sort is necessary?

Sampleman
  • 45
  • 3
  • 4
    Do not remove items from a list you are currently iterating over. Generate a new list instead (or - in your special case - use `set(...)`). – Jan Sep 08 '20 at 14:53
  • @Sampleman if you do `for i, x in enumerate(o)`, and print `i` as well as the current version of `o`, you will see what is happening with the index as you remove things. – michjnich Sep 08 '20 at 15:02
  • 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) – Wups Sep 08 '20 at 15:46

1 Answers1

3

When you remove item x, it shifts the list you are iterating on. Therefore it skips three since in the iteration point is at index 1. Instead do not remove from the current list but make a copy to do your calculations

 o = [2,3,4,5,2,4,5]
 ob = list(o)
 for x in o:
   print(x)
   ob.remove(x)
   if x not in ob:
       print("NOT REDUNDANT" + str(x))

But then you’ll need to check if you’ve already marked something as redundant already like the 2 so you don’t print it out multiple times. I’ll leave that to you.

Edward Romero
  • 2,905
  • 1
  • 5
  • 17
  • so does it mean "for x in y" simply iterates using an incrementing index no matter what happened with the list during the loop? So the removal would lead to all elements behind the removed elements shift to its current index -1, right? This would explain how a dump increment + the shift on a removal leads to this behavior. – Sampleman Sep 08 '20 at 21:04
  • It’s basically changing the list and the iterators don’t know of the change. So it’s not good practice to change what you’re iterating on. Here is a good document that talks about iterators and how they work https://www.programiz.com/python-programming/iterator#what – Edward Romero Sep 08 '20 at 21:14