How to filter a list

Question:

Im writing a simple function to take out any odd numbers from a list and return a list of only the even ones.

def purify(numbers):
    for i in numbers:
        if i%2!=0:
            numbers.remove(i)
    return numbers    

print(purify([4,5,5,4]))

However, the above returns:

[4, 5, 4]

Why doesn’t the second 5 get removed as it also meets the if condition?

Im looking less for a different method to the problem and more to understand why this happens.

Asked By: user2679806

||

Answers:

When you remove an item, the items that follow get moved one position to the left. This results in the loop skipping some items.

BTW, a more idiomatic way to write that code is

numbers = [num for num in numbers if num % 2 == 0]
Answered By: NPE
>>> listToPurify = [1, 2, 2, 3, 4, 5, 6, 6, 5]
>>> purified = [i for i in listToPurify if i % 2]
>>> purified
[1, 3, 5, 5]

Seems that NPE posted this before me! If you’re confused about list comprehensions, check out here.

If you’d prefer to use a for loop, you’re going to have to deal with the fact that the length of the list is changing.

Answered By: vroomfondel

Instead of removing from numbers, try creating a new list appending only the values that meet your conditions.

def purify(numbers):
    newNumber = []
    for i in numbers:
        if i%2 ==0:
           newNumber.append(i)
    return newNumber    

>>>print purify([4,5,5,4])
[4, 4]

Or even simpler:

def purify(numbers):
    return [i for i in numbers if i % 2 == 0]

print purify([4,5,5,4])
Answered By: user1786283

You almost have it. just add [:] after for i in numbers which will iterate through a copy of the list.

def purify(numbers):
    for i in numbers[:]:
        if i%2!=0:
            numbers.remove(i)
    return numbers    

print purify([4,5,5,4])

Theres a good explanation below

python remove duplicates from 2 lists

Answered By: von Mises

For more clear picture print the list in each iteration and see what is happening to list and see how the iteration continues.

# i have taken all odd number to try to remove all numbers from list
>>> list = [1,3,5,7]
>>> for num in list:
...     if num % 2 != 0:
...         list.remove(num)
...     print(list)
...
[3, 5, 7]
[3, 7]

You could see that elements moved one position to the left on each remove().

Answered By: subhash kumar singh

One option I didn’t see mentioned was, ironically filter:

>>> filter(lambda x: not x % 2, [4,5,5,4])
[4, 4]
Answered By: Burhan Khalid
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.