0

Im new at python and also at programming. My code is:

xxx = ['cc','bb','aa','qq','zz']
for k in xxx:
    if k[0] != 'a':
        xxx.remove(k)
print xxx

I'm expecting to get output xxx to be = aa or ['aa'].

But instead my output ['bb', 'aa', 'zz']

Psidom
  • 209,562
  • 33
  • 339
  • 356
  • 3
    You need a `filter` or list-comprehension `[i for i in xxx if i[0] == 'a']`, and should avoid removing elements while looping through the list. – Psidom Aug 16 '16 at 19:54
  • 1
    Possible duplicate of [Remove items from a list while iterating in Python](http://stackoverflow.com/questions/1207406/remove-items-from-a-list-while-iterating-in-python) – Moses Koledoye Aug 16 '16 at 20:00
  • Thx, but still shouldn't it remove all elements except 'aa' ? :) – ruslanas re Aug 16 '16 at 20:00
  • Here's a comment. I can't IMAGINE what manner of curriculum elects Python as one's introductory language. Funny, but I should think it would be good to learn about, like, registers and addresses and stacks before one learns about superclasses and introspection. But that's just me. – Bruce David Wilner Aug 16 '16 at 20:06

2 Answers2

0

You're trying to modify a list in place as you're trying to remove items while iterating, which can lead to an assortment of strange unwanted behaviour. Here are some solutions:

>>> [i for i in ['cc','bb','aa','qq','zz'] if i[0] == 'a']  # Returns new list.
['aa']

or

>>> filter(lambda x: x[0] == 'a', ['cc','bb','aa','qq','zz'])  # New list.
['aa']

or

>>> x = ['cc', 'bb', 'aa', 'qq', 'zz']
>>> l = []  # New List
>>> for e in x:
>>>     if e[0] == 'a':
>>>         l.append(e)
>>> print l
['aa']

or

>>> x = ['cc', 'bb', 'aa', 'qq', 'zz']  # In place.
>>> for e in x[:]:
>>>     if e[0] != 'a':
             x.remove(e)

>>> print x
['aa']
ospahiu
  • 3,465
  • 2
  • 13
  • 24
0

Removing elements from a list while iterating through it (at least the way you are doing it) can be tricky. Let's go through it step-by-step:

xxx = ['cc','bb','aa','qq','zz']
for k in xxx:

You're going to go through each element in the list. The first element is 'cc', which doesn't start with an 'a' so it is removed. Now 'bb' is the first element and 'aa' is the second. In other words:

xxx = ['bb','aa','qq','zz']

BUT the for loop, which only knows it has looked at one element, just moves on to the second element without realizing things have shifted! The second element is now 'aa', which is left alone. Then the loop moves to the third element, 'qq', and removes it, leaving:

xxx = ['bb','aa','zz']

The for loop sees a list with three elements and knows it has looked at three elements and believes it is done, even though it skipped 'bb' and 'zz' completely.

As others have suggested, you can use a list comprehension instead, though you should definitely google and read up on how they work before applying them.

[i for i in ['cc','bb','aa','qq','zz'] if i[0] == 'a']

In the future, I recommend putting print statements inside the for loop while debugging, just to see what's going on. For example, you probably would have figured this out on your own if you had:

for k in xxx:
    print k
    if k[0] != 'a':
        xxx.remove(k)
Noam
  • 550
  • 2
  • 11