filter()

Keep items where a predicate returns truthy — lazily. The functional cousin of a filtered comprehension.

Built-in functionPython 1.0+
Common call
list(filter(None, items))
Returns
a lazy filter iterator — wrap in list() to materialize
Replaces
a comprehension: `[x for x in items if pred(x)]`
Watch out
None as predicate means "keep truthy items"; iterator is consumed on first pass
filter(predicatepredicateA function returning True/False (or truthy/falsy) per item. Special case: None means "keep items that are themselves truthy".type: callable | None · required, iterableiterableThe source items. Any iterable works.type: iterable · required)
filter

Parameters

NameTypeRequiredDescription
predicatecallable | NoneyesA function returning True/False (or truthy/falsy) per item. Special case: None means "keep items that are themselves truthy".
iterableiterableyesThe source items. Any iterable works.

Return value

filterA lazy iterator yielding items where predicate(item) is truthy. If predicate is None, keeps items that are TRUTHY themselves.

Common patterns

Keep truthy items only
The special-case `filter(None, iterable)` — the idiomatic drop-falsy pattern.
active = list(filter(None, items))    # drops 0, "", [], None, False
Named predicate
Use the unbound method — same result as a comprehension with a call.
digits = list(filter(str.isdigit, tokens))
Chain with map for a pipeline
Lazy: no intermediate list is built.
result = list(map(int, filter(str.isdigit, tokens)))
When a comprehension reads better
For non-trivial predicates, a comprehension is often clearer.
# instead of: filter(lambda x: x % 2 == 0 and x > 0, xs)
positives_even = [x for x in xs if x % 2 == 0 and x > 0]

Examples

1. Keep positive
list(filter(lambda x: x > 0, [-1, 0, 1, 2]))
Returns
[1, 2]
2. Predicate is None
list(filter(None, [0, 1, "", "hi", None]))
Returns
[1, "hi"] # truthy only
3. String method as pred
list(filter(str.isdigit, ["a", "1", "b", "2"]))
Returns
["1", "2"]
4. Empty gives empty
list(filter(None, []))
Returns
[]
5. All match
list(filter(lambda x: x > 0, [1, 2, 3]))
Returns
[1, 2, 3]
6. None match
list(filter(lambda x: x > 100, [1, 2, 3]))
Returns
[]

Pitfalls

1. filter() returns an ITERATOR, not a list
In Python 2 it returned a list; Python 3 made it lazy. Printing a filter object shows `<filter object at ...>` — call list() to materialize.
Printed iterator
print(filter(None, [1, 0, 2]))
<filter object at 0x...>
Wrap in list
print(list(filter(None, [1, 0, 2])))
[1, 2]
2. Iterator is CONSUMED on first pass
Once iterated, a filter iterator is exhausted. Trying to reuse it gives an empty iterator.
Empty second time
f = filter(None, items)
list(f)  # results
list(f)  # []
exhausted
Materialize once
result = list(filter(None, items))
reusable
3. predicate=None means &quot;keep truthy&quot;, NOT &quot;keep everything&quot;
Newcomer trap. `filter(None, items)` does NOT return items untouched — it drops every falsy item (0, "", [], None, False). If you truly want &quot;keep everything&quot;, you did not need filter at all.
Assumed identity
list(filter(None, [0, 1, 2]))
[1, 2] # 0 dropped
Use lambda
list(filter(lambda x: True, [0, 1, 2]))
[0, 1, 2] # actually keep all
4. A comprehension usually reads better than filter+lambda
filter(lambda x: pred, items) is functionally identical to [x for x in items if pred] but the comprehension is more Pythonic. Reach for filter when the predicate is already named.
filter + lambda
list(filter(lambda x: x > 0, xs))
works, but stiff
Comprehension
[x for x in xs if x > 0]
idiomatic

When to use

Use it
  • Applying a NAMED predicate — `filter(str.isdigit, ...)`
  • The special `filter(None, iterable)` to drop falsy items
  • Lazy pipelines chained with map()
  • Interop with functional-style libraries expecting iterators
Reach for something else
  • `filter(lambda x: ...` — use a comprehension instead
  • Need to iterate multiple times → wrap in list()
  • Rich filtering (multiple predicates) → comprehension with `and`
  • Filter AND modify → chain with map, or use a comprehension

Notes

Complexity
O(1) to construct; O(n) to iterate; per-item cost is predicate()
Return
A filter iterator — lazy
CPython impl
Python/bltinmodule.c :: builtin_filter
Memory
O(1) — no intermediate list is built
Thread-safe
Depends on predicate and the underlying iterable

FAQ

Behaviorally almost identical, but filter is LAZY (returns an iterator) while a comprehension with `if` is EAGER (returns a list). For a named predicate, filter is compact. For an inline test, the comprehension reads better.

History

1.0
filter() has been a builtin since Python 1.0 — returned a list.
3.0
Return type changed from list to lazy iterator.