Reputation: 121
I am trying to iterate numList and delete all values less than 8 (target). Both 2 & 5 are removed correctly but 3 & 7 are not.
numList = [2, 3, 5, 7, 11, 13, 17, 19]
for n in numList:
print('Testing: {}'.format(n))
if n < 8:
print('-----REMOVING: {}'.format(n))
numList.remove(n)
EXPECTED RESULTS:
Testing: 2
-----REMOVING: 2
Testing: 3
-----REMOVING: 3
Testing: 5
-----REMOVING: 5
Testing: 7
-----REMOVING: 7
Testing: 11
Testing: 13
Testing: 17
Testing: 19
Expecting: [11, 13, 17, 19]
ACTUAL RESULTS
Testing: 2
-----REMOVING: 2
Testing: 5
-----REMOVING: 5
Testing: 11
Testing: 13
Testing: 17
Testing: 19
Actual: [3, 7, 11, 13, 17, 19]
Upvotes: 2
Views: 111
Reputation: 356
Python starts by making a list of indices to loop through, and then looping like a for loop in C, but you are removing items from the list while it's looping.
There are 8 items in your list to start, so imagine python internally decides it's going to loop 8 times, and each time it will access element "i" in your list.
[2, 3, 5, 7, 11, 13, 17, 19]
First it accesses the first element (which is 2). Then you remove 2, so the list now looks like
[3, 5, 7, 11, 13, 17, 19]
Now it accesses the second element (which is 5).
When you wrote the code, you may have expected that the second element would always be considered "3" as it looped through.
There are a few ways you could handle this. One way that is nice from a python perspective is to use a list comprehension syntax:
numList = [n for n in numList if n >= 8]
If you wanted to, you don't have to overwrite numList here, you could instead assign the right side of the equals sign to a new list name.
Upvotes: 1
Reputation: 85492
Never change the size of list you iterate over. Better make a new list:
>>> numList = [2, 3, 5, 7, 11, 13, 17, 19]
>>> [x for x in numList if x >= 8]
[11, 13, 17, 19]
Upvotes: 0
Reputation: 20434
This is because you are removing from a list
that you are iterating over.
You need to make a copy of the list
first then iterate through that:
numList = [2, 3, 5, 7, 11, 13, 17, 19]
for n in numList[:]:
print('Testing: {}'.format(n))
if n < 8:
print('-----REMOVING: {}'.format(n))
numList.remove(n)
which gives:
Testing: 2
-----REMOVING: 2
Testing: 3
-----REMOVING: 3
Testing: 5
-----REMOVING: 5
Testing: 7
-----REMOVING: 7
Testing: 11
Testing: 13
Testing: 17
Testing: 19
Note that it is more Pythonic to use a list-comprehension
:
numList = [n for n in numList if n >= 8]
which gives:
[11, 13, 17, 19]
Upvotes: 1