-1
b = [1,2,3,4,5,6,7]
    for n in b:
        if n > 3:
            b.remove(n)

I print b, and get the following list:

[1,2,3,5,7]

Why are 5 and 7 still present? I can make a function that pretty much does the same thing and removes all numbers from the list about 3, so why can't I do the same in Terminal?

jub0bs
  • 60,866
  • 25
  • 183
  • 186
cornbread
  • 28
  • 7

3 Answers3

3

This is a well-known issue. Iterators are not reliable when you modify the underlying collection while using the iterator.

As for the behavior you experience:

With CPython, the list iterator is represented by an index into the array. If you remove an item from the list at the iterator position or before it while still iterating over it, the iterator jumps forward. The iterator position index is still the same, but all items "under" the iterator have just moved to the left by one position. This makes the iterator skip one element. Hence you only remove every second item.

l = [1, 2, 3, 4]
        ^it(pos=1)

l.remove(2)
l = [1, 3, 4]
        ^it(pos=1)

it.next()     # automatically at the end of each for loop 
l = [1, 3, 4] # we just skipped over an item
           ^it(pos=2)

Here's a nice little treatise on the topic from @mgiuca.

Interestingly enough, removing items after the iterator position is safe with the current implementation.

In short: don't modify collections while iterating over them. Alternatives for lists: Remove items from a list while iterating in Python

dhke
  • 15,008
  • 2
  • 39
  • 56
1

Thats because you are iterating over the same list. Try this:

b = [1,2,3,4,5,6,7]
c = b[:]
for n in c:
    if n > 3:
        b.remove(n)

If you see the below image, now I creating two different list.

enter image description here

python
  • 4,403
  • 13
  • 56
  • 103
0

When you remove an element, the array is modified (elements shifted to the left), so the next iteration takes you to the next element bypassing the shifted element. That is to say, the array is modified and the loop advances to the next index. That is why you notice a jump every time an element is removed.

mansoor.khan
  • 2,309
  • 26
  • 39