GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing zetcode.com — Python filter list - list comprehensions, filter, and itertools Python filter listlast modified October 30, 2026 Python 3.15 In this article we show how to filter lists in Python. FilteringA filtering operation processes a data structure, such as a list, and produces a new data structure containing exactly those elements for which the given predicate returns true. A predicate is a single-argument function which returns a boolean value. In Python, any value that is true in a boolean context counts as true.
The most common tools for filtering lists are list comprehensions and the
built-in Filtering with a list comprehension
A list comprehension is a syntactic construct which creates a
list based on an existing iterable. A positive.py
vals = [-2, 1, -4, 2, 0, -1, 12, -3] positive = [e for e in vals if e > 0] print(positive) We have a list of integers. We create a new list of positive integers. positive = [e for e in vals if e > 0] The condition is applied on each element; an element is included in the new list only if it satisfies the condition. The original list is not modified. $ python positive.py [1, 2, 12] Odd and even numbersEven numbers are integers that are exactly divisible by two; odd numbers leave a remainder of one. odd_values.py
vals = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] odd = [e for e in vals if e % 2] even = [e for e in vals if e % 2 == 0] print(odd) print(even)
The example creates filtered lists of odd and even values with the
$ python odd_values.py [1, 3, 5, 7, 9, 11] [2, 4, 6, 8, 10, 12] Filtering by typeWe can filter values by their data types. by_type.py
vals = ['a', 4, 'c', 12, 'e', 3.5, True, 'd', None] ints = [e for e in vals if isinstance(e, int)] strict_ints = [e for e in vals if isinstance(e, int) and not isinstance(e, bool)] strs = [e for e in vals if isinstance(e, str)] numbers = [e for e in vals if isinstance(e, (int, float)) and not isinstance(e, bool)] print(ints) print(strict_ints) print(strs) print(numbers)
In the example, we have a list that is a mix of integers, strings, a float,
a boolean, and strict_ints = [e for e in vals if isinstance(e, int) and not isinstance(e, bool)]
The $ python by_type.py [4, 12, True] [4, 12] ['a', 'c', 'e', 'd'] [4, 12, 3.5] Multiple conditionsWe can have multiple conditions in a list comprehension. multiple_conditions.py
vals = [9, -2, 5, 14, 22, -11, 7, -19, 23, 10] res1 = [e for e in vals if e % 2 == 0 if e > 0] res2 = [e for e in vals if e % 2 == 0 and e > 0] res3 = [e for e in vals if e < 0 or e > 20] res4 = [e for e in vals if 0 < e < 10] print(res1) print(res2) print(res3) print(res4)
Two consecutive $ python multiple_conditions.py [14, 22, 10] [14, 22, 10] [-2, 22, -11, -19, 23] [9, 5, 7] The filter function
The filter_fun.py
words = ['sky', 'cloud', 'wood', 'forest', 'tie', 'nice', 'cup'] filtered = filter(lambda e: len(e) == 3, words) print(filtered) print(list(filtered)) print(list(filtered))
With the filtered = filter(lambda e: len(e) == 3, words) As a predicate, we have an anonymous function which checks the length of the current element. print(filtered) print(list(filtered)) print(list(filtered))
The $ python filter_fun.py <filter object at 0x7e2e58a0fb50> ['sky', 'tie', 'cup'] [] Named predicates
The filter_named.py
def is_palindrome(word):
return word == word[::-1]
words = ['level', 'forest', 'radar', 'sky', 'kayak', 'cup', 'noon']
print(list(filter(is_palindrome, words)))
print([word for word in words if is_palindrome(word)])
codes = ['12', 'x7', '305', '', '4a', '99']
print(list(filter(str.isdigit, codes)))
We find the palindromes in a list of words with $ python filter_named.py ['level', 'radar', 'kayak', 'noon'] ['level', 'radar', 'kayak', 'noon'] ['12', '305', '99'] Removing falsy values
If the predicate is filter_none.py
vals = [0, 1, '', 'sky', None, [], [0], False, 2.5, {}]
print(list(filter(None, vals)))
print([e for e in vals if e])
lines = ['first', '', 'second', ' ', 'third']
print([line for line in lines if line.strip()])
Zero, empty strings, $ python filter_none.py [1, 'sky', [0], 2.5] [1, 'sky', [0], 2.5] ['first', 'second', 'third'] Filtering stringsString methods are useful in filtering conditions. filter_strings.py
words = ['Python', 'perl', 'Go', 'PHP', 'Rust', 'pascal', 'C#', 'Prolog']
print([w for w in words if w.startswith('P')])
print([w for w in words if w.lower().startswith('p')])
print([w for w in words if 'o' in w])
print([w for w in words if len(w) > 4 and w[0].isupper()])
We find words starting with P, with a case-insensitive variant, words containing the letter o, and capitalized words longer than four characters. $ python filter_strings.py ['Python', 'PHP', 'Prolog'] ['Python', 'perl', 'PHP', 'pascal', 'Prolog'] ['Python', 'Go', 'Prolog'] ['Python', 'Prolog'] Filtering dictionariesData often comes as a list of dictionaries. filter_dicts.py
users = [
{'name': 'John Doe', 'occupation': 'gardener', 'age': 34},
{'name': 'Roger Roe', 'occupation': 'driver', 'age': 19},
{'name': 'Lucy Smith', 'occupation': 'teacher', 'age': 46},
{'name': 'Paul Novak', 'occupation': 'driver', 'age': 28},
]
drivers = [u['name'] for u in users if u['occupation'] == 'driver']
print(drivers)
older = [u for u in users if u['age'] > 30]
for user in older:
print(user)
prices = {'apple': 1.2, 'banana': 0.5, 'cherry': 4.0, 'plum': 2.1}
print({k: v for k, v in prices.items() if v < 2})
We get the names of the drivers and the users older than thirty. The condition and the expression of the comprehension are independent, so we can filter by one key and collect another. The last line filters a dictionary with a dictionary comprehension. $ python filter_dicts.py
['Roger Roe', 'Paul Novak']
{'name': 'John Doe', 'occupation': 'gardener', 'age': 34}
{'name': 'Lucy Smith', 'occupation': 'teacher', 'age': 46}
{'apple': 1.2, 'banana': 0.5}
Filtering objectsObjects are filtered by their attributes. filter_objects.py
from dataclasses import dataclass
@dataclass
class Product:
name: str
price: float
in_stock: bool
products = [
Product('keyboard', 49.9, True),
Product('mouse', 19.9, False),
Product('monitor', 189.0, True),
Product('cable', 4.5, True),
]
available = [p for p in products if p.in_stock]
cheap = [p.name for p in available if p.price < 50]
print(len(available))
print(cheap)
We first select the products in stock and then the cheap ones among them. $ python filter_objects.py 3 ['keyboard', 'cable'] Partitioning a list
Sometimes we need both the matching and the non-matching elements. The
partition.py
from itertools import filterfalse
vals = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def is_even(n):
return n % 2 == 0
print(list(filter(is_even, vals)))
print(list(filterfalse(is_even, vals)))
passed, failed = [], []
for score in [72, 45, 90, 38, 66, 51]:
(passed if score >= 50 else failed).append(score)
print(passed, failed)
Calling $ python partition.py [2, 4, 6, 8, 10] [1, 3, 5, 7, 9] [72, 90, 66, 51] [45, 38] The takewhile and dropwhile functions
The take_drop.py
from itertools import takewhile, dropwhile temps = [3, 5, 8, 12, 15, 11, 7, 4] print([t for t in temps if t < 10]) print(list(takewhile(lambda t: t < 10, temps))) print(list(dropwhile(lambda t: t < 10, temps)))
The list comprehension keeps all temperatures below ten. The
$ python take_drop.py [3, 5, 8, 7, 4] [3, 5, 8] [12, 15, 11, 7, 4] Finding the first matchTo find only the first matching element, we do not need to filter the whole list. first_match.py
vals = [7, 13, 22, 9, 40, 18] first_even = next((e for e in vals if e % 2 == 0), None) print(first_even) first_big = next((e for e in vals if e > 100), None) print(first_big) print(any(e > 30 for e in vals))
The $ python first_match.py 22 None True Filtering in place
List comprehensions and in_place.py
vals = [1, 2, 2, 3, 2, 4]
for e in vals:
if e == 2:
vals.remove(e)
print(vals)
vals = [1, 2, 2, 3, 2, 4]
alias = vals
vals[:] = [e for e in vals if e != 2]
print(vals, alias)
The loop skips an element after each removal, because the following elements shift one position to the left; one 2 is left in the list. To filter a list in place, we assign the filtered list to the full slice. The list object is kept, so other references to it see the change. $ python in_place.py [1, 3, 2, 4] [1, 3, 4] [1, 3, 4] Removing duplicatesA filter can remove duplicates while preserving the order of the elements. unique_values.py
words = ['sky', 'cup', 'sky', 'wood', 'cup', 'forest', 'sky']
print(list(dict.fromkeys(words)))
seen = set()
unique = []
for word in words:
if word not in seen:
seen.add(word)
unique.append(word)
print(unique)
Dictionary keys are unique and keep the insertion order, so
$ python unique_values.py ['sky', 'cup', 'wood', 'forest'] ['sky', 'cup', 'wood', 'forest'] Filtering with a loop
The following example uses a plain custom_filter.py
vals = [-1, 2, 0, 11, 9, -3, -4, 3]
positive = []
for val in vals:
if val > 0:
positive.append(val)
print(positive)
We use a $ python custom_filter.py [2, 11, 9, 3] Lazy filteringA generator expression filters lazily; it produces the elements one by one when they are requested and does not build a list. lazy_filter.py
import sys nums = range(1_000_000) squares = [n * n for n in nums if n % 7 == 0] lazy = (n * n for n in nums if n % 7 == 0) print(sys.getsizeof(squares), sys.getsizeof(lazy)) print(sum(lazy)) print(sum(squares))
The list of squares of multiples of seven takes over a megabyte of memory,
while the generator object takes a few hundred bytes. Both give the same sum.
Like the $ python lazy_filter.py 1283160 216 47619404762214285 47619404762214285 PerformanceWe compare the speed of the three approaches. timing.py
import timeit
setup = 'vals = list(range(100_000))'
tests = {
'comprehension': '[e for e in vals if e % 2]',
'filter + lambda': 'list(filter(lambda e: e % 2, vals))',
'for loop': '''
res = []
for e in vals:
if e % 2:
res.append(e)
''',
}
for name, stmt in tests.items():
t = min(timeit.repeat(stmt, setup, number=20, repeat=5))
print(f'{name:16} {t / 20 * 1000:.2f} ms')
We filter the odd numbers of a list of 100,000 integers and take the best
of five measurements. The list comprehension is the fastest. The
$ python timing.py comprehension 2.24 ms filter + lambda 3.35 ms for loop 2.35 ms SourceList comprehensions - Python documentation In this article we have filtered lists in Python. AuthorMy name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming. List all Python tutorials. |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |