0

Code first:

li = [32,45,23,66,66,89,27]
print li
for k in li:
    if k == 66:
        li.remove(k)
print li

Result:

> [32, 45, 23, 66, 66, 89, 27] 

> [32, 45, 23, 66, 89, 27]

Here is my question: when I remove the first 66, the second one and the other items will move forward one index, and the next k will be 89. The second 66 is still there. How can I remove it?

paulmelnikow
  • 16,895
  • 8
  • 63
  • 114
sashimi
  • 793
  • 2
  • 8
  • 14
  • 2
    You shouldn't remove items while you iterate through them, it is better to use a list comprehension to make a new list with the correct values. – jamylak May 11 '12 at 03:58

3 Answers3

3

The most common way to do this is to iterate over a copy of a list, rather than the original list:

for k in li[:]:
    #do stuff

I prefer to use a list comprehension however:

[k for k in li if k != 66]
Joel Cornett
  • 24,192
  • 9
  • 66
  • 88
2

See my answer to Loop problem while iterating through a list and removing recurring elements to understand why you get this problem.

In this case, you can just do:

li = [item for item in li if item != 66]

to make a new list.

The list comprehension will also be faster if you have to do a lot of removes because each remove has to traverse the whole list, while the list comprehension traverses the whole list only once.

Community
  • 1
  • 1
agf
  • 171,228
  • 44
  • 289
  • 238
0

I guess what you want to do is this. So in your case:

li = [32,45,23,66,66,89,27]
print li
li[:] = [x for x in li if x != 66]
print li

of course if you want to do it with a normal for loop you can always iterate li reversed:

li = [32,45,23,66,66,89,27]
print li
for k in reversed(li):
    if k == 66:
        li.remove(k)
print li

But notice, that this is very inefficient. Because remove searches for the first occurance and removes that. So you effectively iterate the list many times.

Community
  • 1
  • 1
Qlaus
  • 885
  • 5
  • 15
  • We don't know that he needs to maintain the same actual list object. He probably doesn't. – agf May 11 '12 at 04:04
  • There's no reason to mutate the old list. In this case, rebinding name `li` is actually slightly (about 10%) faster. Not to mention it avoids unnecessary code complexity. – Joel Cornett May 11 '12 at 04:07