How to use Python filter()
By Flavio Copes
Learn how to use the Python filter() function to keep only the items of an iterable that pass a test, using a named function or a concise lambda function.
filter() is a built-in Python function that keeps only the items of an iterable that pass a test. You pass it a function and an iterable, and you get back only the items for which the function returns True.
Python provides 3 useful global functions we can use to work with collections: map(), filter() and reduce().
Tip: sometimes list comprehensions make more sense and are generally considered more pythonic
filter() takes an iterable and returns a filter object, which is another iterable, but without some of the original items.
You do so by returning True or False from the filtering function:
numbers = [1, 2, 3]
def is_even(n):
return n % 2 == 0
result = filter(is_even, numbers)
print(list(result)) # [2]
The original list is not touched. filter() gives you a new iterable with the items that passed the test.
You can use a lambda function to make the code more concise:
numbers = [1, 2, 3]
result = filter(lambda n: n % 2 == 0, numbers)
print(list(result)) # [2]
The filter object is consumed once
filter() does not return a list. It returns a lazy iterator. Items are tested one by one, only when you ask for them.
This means you can only loop over the result once. The second time, it’s empty:
result = filter(lambda n: n % 2 == 0, [1, 2, 3])
print(list(result)) # [2]
print(list(result)) # []
This is the most common pitfall. If you need the values more than once, convert the result to a list right away:
evens = list(filter(lambda n: n % 2 == 0, [1, 2, 3]))
Now evens is a regular list and you can use it as many times as you want.
Filtering out falsy values
You can pass None as the function. In that case filter() keeps only the truthy items, dropping things like 0, empty strings and None:
values = [0, 1, '', 'hello', None]
print(list(filter(None, values))) # [1, 'hello']
This is a quick way to clean up a list of mixed data.
When to use a list comprehension instead
The same even-numbers filter written as a list comprehension:
numbers = [1, 2, 3]
evens = [n for n in numbers if n % 2 == 0]
print(evens) # [2]
My advice: reach for filter() when you already have a named test function, like is_even. When the condition is a short inline expression, the list comprehension reads better.
Related posts about python: