11.2. FP Apply Filter

  • filter(callable, *iterables)

  • Select elements from sequence

  • Generator (lazy evaluated)

  • required callable - Function

  • required iterables - 1 or many sequence or iterator objects

The filter function in Python is a built-in function that allows you to filter out elements from a given iterable based on a specified condition. It takes two arguments: a function that returns a Boolean value and an iterable (such as a list, tuple, or set) that you want to filter.

The function is applied to each element in the iterable, and only those elements for which the function returns True are included in the result. The filtered elements are returned as an iterator, which can be converted to a list or other iterable if desired.

Here's an example of using the filter function to filter out even numbers from a list:

>>> data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>>
>>> def is_odd(n):
...     return n % 2 != 0
>>>
>>> result = filter(is_odd, data)
>>> list(result)
[1, 3, 5, 7, 9]

In this example, the is_odd function returns True for odd numbers and False for even numbers. The filter function is used to apply this function to each element in the numbers list and return only those elements for which is_odd returns True. The resulting list contains only the odd numbers from the original list.

>>> def even(x):
...     return x % 2 == 0
>>>
>>> result = (x for x in range(0,5) if even(x))
>>> result = filter(even, range(0,5))
>>>
>>> result = (x for x in range(0,5) if x%2==0)
>>> result = filter(lambda x: x%2==0, range(0,5))
>>> from inspect import isgeneratorfunction, isgenerator
>>>
>>>
>>> def even(x):
...     return x % 2 == 0
>>>
>>>
>>> isgeneratorfunction(filter)
False
>>>
>>> result = filter(even, [1,2,3])
>>> isgenerator(result)
False

11.2.1. Problem

Plain code:

>>> def even(x):
...     return x % 2 == 0
>>>
>>>
>>> DATA = [1, 2, 3, 4, 5, 6]
>>> result = []
>>>
>>> for x in DATA:
...     if even(x):
...         result.append(x)
>>>
>>> print(result)
[2, 4, 6]

Comprehension:

>>> def even(x):
...     return x % 2 == 0
>>>
>>>
>>> DATA = [1, 2, 3, 4, 5, 6]
>>> result = [x for x in DATA if even(x)]
>>>
>>> print(result)
[2, 4, 6]

11.2.2. Solution

>>> def even(x):
...     return x % 2 == 0
>>>
>>>
>>> DATA = [1, 2, 3, 4, 5, 6]
>>> result = filter(even, DATA)
>>>
>>> list(result)
[2, 4, 6]

11.2.3. Lazy Evaluation

>>> def even(x):
...     return x % 2 == 0
>>>
>>>
>>> DATA = [1, 2, 3, 4, 5, 6]
>>> result = filter(even, DATA)
>>>
>>> next(result)
2
>>> next(result)
4
>>> next(result)
6
>>> next(result)
Traceback (most recent call last):
StopIteration

11.2.4. Performance

  • Date: 2024-12-01

  • Python: 3.13.0

  • IPython: 8.30.0

  • System: macOS 15.1.1

  • Computer: MacBook M3 Max

  • CPU: 16 cores (12 performance and 4 efficiency) / 3nm

  • RAM: 128 GB RAM LPDDR5

>>> def even(x):
...     return x % 2 == 0
>>>
>>>
>>> data = [1, 2, 3, 4, 5, 6]
>>> # doctest: +SKIP
... %%timeit -n 1000 -r 1000
... result = [x for x in data if even(x)]
245 ns ± 46.2 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
249 ns ± 43.4 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
245 ns ± 48.2 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
>>> # doctest: +SKIP
... %%timeit -n 1000 -r 1000
... result = list(filter(even, data))
260 ns ± 48.3 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
264 ns ± 47 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
260 ns ± 41.9 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)

11.2.5. Use Case - 1

>>> from pprint import pprint
>>> users = [
...     {'age': 41, 'username': 'mwatney'},
...     {'age': 40, 'username': 'mlewis'},
...     {'age': 39, 'username': 'rmartinez'},
...     {'age': 40, 'username': 'avogel'},
...     {'age': 29, 'username': 'bjohanssen'},
...     {'age': 36, 'username': 'cbeck'},
... ]
>>> def above40(person):
...     return person['age'] >= 40
>>>
>>> def under40(person):
...     return person['age'] < 40
>>> result = filter(above40, users)
>>> pprint(list(result))
[{'age': 41, 'username': 'mwatney'},
 {'age': 40, 'username': 'mlewis'},
 {'age': 40, 'username': 'avogel'}]
>>> result = filter(under40, users)
>>> pprint(list(result))
[{'age': 39, 'username': 'rmartinez'},
 {'age': 29, 'username': 'bjohanssen'},
 {'age': 36, 'username': 'cbeck'}]

11.2.6. Use Case - 2

>>> from pprint import pprint
>>> users = [
...     {'is_staff': True,  'username': 'mwatney'},
...     {'is_staff': True,  'username': 'mlewis'},
...     {'is_staff': True,  'username': 'rmartinez'},
...     {'is_staff': False, 'username': 'avogel'},
...     {'is_staff': True,  'username': 'bjohanssen'},
...     {'is_staff': True,  'username': 'cbeck'},
... ]
>>>
>>>
>>> def can_login(user):
...     return user['is_staff']
>>>
>>> result = filter(can_login, users)
>>> pprint(list(result))
[{'is_staff': True, 'username': 'mwatney'},
 {'is_staff': True, 'username': 'mlewis'},
 {'is_staff': True, 'username': 'rmartinez'},
 {'is_staff': True, 'username': 'bjohanssen'},
 {'is_staff': True, 'username': 'cbeck'}]

11.2.7. Use Case - 3

>>> users = [
...     'mwatney',
...     'mlewis',
...     'rmartinez',
...     'avogel',
...     'bjohanssen',
...     'cbeck',
... ]
>>>
>>> staff = [
...     'mwatney',
...     'mlewis',
...     'ptwardowski',
...     'jjimenez',
... ]
>>>
>>>
>>> def can_login(user):
...     return user in staff
>>>
>>>
>>> result = filter(can_login, users)
>>> list(result)
['mwatney', 'mlewis']

11.2.8. Assignments

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Functional Filter Even
# - Difficulty: easy
# - Lines: 1
# - Minutes: 3

# %% English
# 1. Define `result: filter` with even numbers from `DATA`
# 2. Use `filter` builtin and `even` function
# 3. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `result: filter` z liczbami parzystymi z `DATA`
# 2. Użyj wbudowanej funkcji `filter` i funkcji `even`
# 3. Uruchom doctesty - wszystkie muszą się powieść

# %% Hints
# - `filter()`

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from inspect import isfunction

>>> assert isfunction(even), \
'Object `even` must be a function'

>>> assert result is not Ellipsis, \
'Assign result to variable: `result`'

>>> assert type(result) is filter, \
'Variable `result` has invalid type, should be filter'

>>> result = tuple(result)
>>> assert type(result) is tuple, \
'Evaluated `result` has invalid type, should be tuple'

>>> assert all(type(x) is int for x in result), \
'All rows in `result` should be int'

>>> result
(2, 4)
"""


DATA = (1, 2, 3, 4)

def even(x):
    return x % 2 == 0


# Define `result: filter` with even numbers from `DATA`
# Use `filter` builtin and `even` function
# type: filter[int]
result = ...