0

I have a simple question about lists

Suppose that I want to delete all 'a's from a list:

list = ['a', 'a', 'b', 'b', 'c', 'c']
for element in list:
    if element == 'a':
        list.remove('a')

print list

==> result:

['a', 'b', 'b', 'c', 'c', 'd', 'd']

I know this is happening because, after I remove the first 'a', the list index gets

incremented while all the elements get pushed left by 1.

In other languages, I guess one way to solve this is to iterate backwards from the end of the list..

However, iterating through reversed(list) returns the same error.

Is there a pythonic way to solve this problem??

Thanks

Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
user2492270
  • 2,215
  • 6
  • 40
  • 56
  • 1
    Dup: [Loop “Forgets” to Remove Some Items](http://stackoverflow.com/questions/17299581/loop-forgets-to-remove-some-items) – Ashwini Chaudhary Dec 09 '13 at 07:59
  • 1
    Reverse iteration isn't helping because you're using `remove`, which loops over the list from the front and removes the first occurence it finds. Don't use `remove` unless you really have no better option. – user2357112 Dec 09 '13 at 08:01
  • Please, don't use a `list` name as varible. – greg Dec 09 '13 at 08:07

3 Answers3

4

One of the more Pythonic ways:

>>> filter(lambda x: x != 'a', ['a', 'a', 'b', 'b', 'c', 'c'])
['b', 'b', 'c', 'c']
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
  • I am curious. What makes this pythonic? I expect, that your way is faster, but one miss placed character and debugging this would drive me to drink. I am fairly new to python and am genuinely curious. – cstrutton Dec 10 '13 at 13:13
  • I suppose because it uses the method defined for this exact purpose: `Return those items of sequence for which function(item) is true.` – Burhan Khalid Dec 10 '13 at 14:18
3

You should never modify a list while iterating over it.

A better approach would be to use a list comprehension to exclude an item:

list1 = ['a', 'a', 'b', 'b', 'c', 'c']
list2 = [x for x in list1 if x != 'a']

Note: Don't use list as a variable name in Python - it masks the built-in list type.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
0

You are correct, when you remove an item from a list while iterating over it, the list index gets out of sync. What both the other existing answers are hinting at is that you need to create a new list and copy over only the items you want.

For example:

existing_list = ['a', 'a', 'b', 'c', 'd', 'e']

new_list = []

for element in existing_list:
    if element != 'a':
        new_list.append(element)

existing_list = new_list
print existing_list

outputs: ['b', 'c', 'd', 'e']

cstrutton
  • 5,667
  • 3
  • 25
  • 32