Filter (Extract/Remove) Items of a List with in Python: filter()
In Python, you can use filter()
to filter (extract/remove) items of a list, tuple, or other iterable that satisfy the conditions.
Note that filter()
can be substituted by list comprehensions or generator expressions, as described later, and in many cases, it is preferable to use them.
For more information on extracting elements of a list using list comprehensions, see the following article.
Basic usage of filter()
The first argument of filter()
is a callable object such as a function to be applied, and the second argument is an iterable object such as a list. Apply the function to the iterable elements and extract items whose result is determined to be True
.
filter()
returns an iterator in Python3
For example, use a lambda expression that returns True
when the value is an even number (i.e., the remainder of the value divided by 2
is 0
).
In Python 3, filter()
returns an iterator of type filter
. Note that using print()
directly on this object will not output its items.
l = [-2, -1, 0, 1, 2]
print(filter(lambda x: x % 2 == 0, l))
# <filter object at 0x10bb38580>
print(type(filter(lambda x: x % 2 == 0, l)))
# <class 'filter'>
The value of the iterator can be retrieved using a for
loop.
for i in filter(lambda x: x % 2 == 0, l):
print(i)
# -2
# 0
# 2
Note that filter()
in Python 2 returns a list, which might cause issues when running Python 2 code in Python 3.
Convert to a list
To convert the result of filter()
to a list, use list()
.
l = [-2, -1, 0, 1, 2]
print(list(filter(lambda x: x % 2 == 0, l)))
# [-2, 0, 2]
Extract and remove elements according to conditions
filter()
extracts elements whose result is determined to be True
by applying the function of the first argument. If you want to remove an element, specify a function whose result is the opposite.
For example, "remove even elements" is equivalent to "extract odd elements".
l = [-2, -1, 0, 1, 2]
print(list(filter(lambda x: x % 2 == 0, l)))
# [-2, 0, 2]
print(list(filter(lambda x: x % 2 != 0, l)))
# [-1, 1]
As demonstrated in the example above, you can replace comparison operators with their opposite equivalents (==
and ! =
, >
and <=
, etc.), or use not
for negation.
For example, extract and remove strings ending with 'e'
.
l_s = ['apple', 'orange', 'strawberry']
print(list(filter(lambda x: x.endswith('e'), l_s)))
# ['apple', 'orange']
print(list(filter(lambda x: not x.endswith('e'), l_s)))
# ['strawberry']
Contrary to filter()
, a function itertools.filterfalse()
is also provided to keep elements that are False
. It is described later.
Apply lambda expressions (lambda
) and functions defined with def
The first argument of filter()
is a callable object.
As in the previous examples, lambda expressions (lambda
) are often used, but of course, it is also possible to specify a function defined with def
.
def is_even(x):
return x % 2 == 0
l = [-2, -1, 0, 1, 2]
print(list(filter(is_even, l)))
# [-2, 0, 2]
Apply multiple conditions
To apply multiple conditions, you can use a lambda expression or function that combines these conditions using and
or or
.
l = [-2, -1, 0, 1, 2]
print(list(filter(lambda x: x % 2 == 0 and x > 0, l)))
# [2]
print(list(filter(lambda x: x % 2 == 0 or x > 0, l)))
# [-2, 0, 1, 2]
Specify None
as the first argument
If None
is specified as the first argument of filter()
, elements determined to be True
(= truthy elements) are extracted.
l_b = [True, False]
print(list(filter(None, l_b)))
# [True]
Not only True
and False
, but also numbers, lists, and strings are evaluated.
For example, in the case of numbers, 0
is regarded as False
and all other numbers are regarded as True
. For lists and strings, if they are empty, they are regarded as False
, otherwise they are regarded as True
.
See the following article for details.
Therefore, if you specify None
as the first argument of filter()
, 0
and empty lists and strings will be removed.
l = [-2, -1, 0, 1, 2]
print(list(filter(None, l)))
# [-2, -1, 1, 2]
l_2d = [[0, 1, 2], [], [3, 4, 5]]
print(list(filter(None, l_2d)))
# [[0, 1, 2], [3, 4, 5]]
l_s = ['apple', '', 'orange', 'strawberry']
print(list(filter(None, l_s)))
# ['apple', 'orange', 'strawberry']
Extract False
elements: itertools.filterfalse()
Contrary to filter()
, a function itertools.filterfalse()
is also provided to keep elements that are False
.
Usage is the same as filter()
. You need to import itertools
.
import itertools
l = [-2, -1, 0, 1, 2]
print(list(itertools.filterfalse(lambda x: x % 2 == 0, l)))
# [-1, 1]
print(list(itertools.filterfalse(lambda x: x % 2 != 0, l)))
# [-2, 0, 2]
l_s = ['apple', 'orange', 'strawberry']
print(list(itertools.filterfalse(lambda x: x.endswith('e'), l_s)))
# ['strawberry']
As mentioned above, the same result can be obtained with filter()
by changing the function of the first argument, but in some cases, itertools.filterfalse()
can be used to write code whose intention is clearer than using filter()
and not
.
If the first argument of itertools.filterfalse()
is set to None
, elements which are determined to be False
(= falsy elements) are extracted.
l = [-2, -1, 0, 1, 2]
print(list(itertools.filterfalse(None, l)))
# [0]
Use list comprehensions and generator expressions instead
The equivalent of filter()
can also be achieved with list comprehensions and generator expressions.
Note that
filter(function, iterable)
is equivalent to the generator expression(item for item in iterable if function(item))
if function is notNone
and(item for item in iterable if item)
if function isNone
. Built-in Functions - filter() — Python 3.11.3 documentation
l = [-2, -1, 0, 1, 2]
print([x for x in l if x % 2 == 0])
# [-2, 0, 2]
print([x for x in l if x % 2 != 0])
# [-1, 1]
l_s = ['apple', 'orange', 'strawberry']
print([x for x in l_s if x.endswith('e')])
# ['apple', 'orange']
print([x for x in l_s if not x.endswith('e')])
# ['strawberry']
l = [-2, -1, 0, 1, 2]
print([x for x in l if x])
# [-2, -1, 1, 2]
l_2d = [[0, 1, 2], [], [3, 4, 5]]
print([x for x in l_2d if x])
# [[0, 1, 2], [3, 4, 5]]
If you want to get a list like list(filter())
, use the list comprehensions, and if you want to get an iterator like filter()
, use a generator expression.
As shown in the following Stack Overflow question, in most cases, using list comprehensions and generator expressions is preferable to filter()
because the code is more concise and clear.
Keep in mind that processing speed can vary due to various factors. If speed is crucial for your use case, it is recommended to perform measurements under conditions that closely match your actual usage.