The built-in filter takes a function and an iterable, and yields only the items for which the function returns a true value. In Python 3 it returns an iterator, not a list.
numbers = [1, 2, 3, 4, 5, 6]
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers))You should see [2, 4, 6]. That is the core idea: test each element, keep those where the predicate is true.
If you only need a single yes/no over a predicate, any() is often simpler than fully consuming a filter iterator—see Python any() and all() for that pattern.
Tested on: Python 3.13.3; kernel 6.14.0-37-generic.
What does filter() do in Python?
filter(function, iterable) walks iterable one item at a time. For each item, Python calls function(item) (or treats the item as true/false when function is None). If the result is true, the item is yielded; otherwise it is skipped. The original iterable is not replaced—filter produces a new stream of references to the same objects unless your function copies or mutates them.
Python filter() syntax
filter(function, iterable)function: a callable taking one argument, orNone(seefilter(None, ...)below).iterable: any iterable (list, tuple, string, dict views, file lines, custom objects, and so on).
The return type in Python 3 is a filter iterator object.
Why filter() returns a filter object
Python 3’s filter() constructs an iterator—you will see something like <filter object at 0x...> if you print the result without converting it. That design saves memory: values are computed on demand as you iterate, instead of building a whole list up front.
Convert filter object to list
Wrap the iterator in list() when you need a concrete list (printing, indexing twice, or passing to APIs that expect a sequence).
nums = [1, 2, 3]
positive = filter(lambda x: x > 0, nums)
print(list(positive))You should see [1, 2, 3].
Filter a list using a normal function
Named predicates stay readable when the condition grows beyond a one-liner.
def is_even(n):
return n % 2 == 0
numbers = [1, 2, 3, 4, 5, 6]
print(list(filter(is_even, numbers)))You should see [2, 4, 6]. For more on sequences, see the Python list guide.
Filter a list using lambda
For small predicates, a lambda keeps the call site compact.
numbers = [1, 2, 3, 4, 5, 6]
print(list(filter(lambda x: x % 2 == 1, numbers)))You should see [1, 3, 5].
Filter strings using filter()
Strings are iterable over characters. Here we keep only ASCII letters.
text = "a1b2c"
print("".join(filter(str.isalpha, text)))You should see abc.
Filter a dictionary using filter()
dict.items() yields (key, value) pairs; filter them, then pass the iterator to dict(...).
scores = {"Alice": 85, "Bob": 40, "Charlie": 72}
passed = dict(filter(lambda item: item[1] >= 50, scores.items()))
print(passed)You should see {'Alice': 85, 'Charlie': 72}. For dict basics, see Python dictionary example.
Filter objects using filter()
Use attributes in the predicate when filtering a list of instances.
class User:
def __init__(self, name, active):
self.name = name
self.active = active
users = [
User("Alice", True),
User("Bob", False),
User("Charlie", True),
]
active_users = list(filter(lambda user: user.active, users))
print([u.name for u in active_users])You should see ['Alice', 'Charlie'].
Use filter(None, iterable)
If the first argument is None, Python uses the identity: items that are falsy (False, None, numeric zero, empty strings, empty containers, and so on) are dropped; truthy values are kept.
values = [0, 1, "", "hello", None, [], [1, 2], False, True]
result = list(filter(None, values))
print(result)You should see [1, 'hello', [1, 2], True].
filter() vs list comprehension
List comprehensions put the expression and condition in one place; many teams find them easier to read for simple filters.
numbers = [1, 2, 3, 4, 5, 6]
even_numbers = [x for x in numbers if x % 2 == 0]
print(even_numbers)You should see [2, 4, 6]. Prefer filter when you already have a reusable function or want lazy evaluation without building a list until you iterate. Prefer a comprehension when the logic is short and local. A generator expression (x for x in numbers if x % 2 == 0) is similarly lazy like filter if you only need iteration once. See list comprehension examples for side-by-side patterns.
filter() with map()
You can chain filter then map when you want to transform the kept items (both are lazy until consumed). See Python map() for transform-only pipelines.
nums = [1, 2, 3, 4]
labels = list(map(str, filter(lambda x: x % 2 == 0, nums)))
print(labels)You should see ['2', '4'].
Common mistakes with filter()
These bullets are reminders; you do not need a separate runnable block for every one, because list(), filter(None, ...), and dict filtering are already shown above. The snippets below only illustrate mistakes that are easy to misread in isolation.
- Forgetting that
filter(...)is an iterator and printing it raw instead of wrapping withlist()or iterating in a loop. - Writing
filter(some_func(), iterable)instead offilter(some_func, iterable)—you must pass the function object, not call it in place unless it returns a callable. - Expecting
filterto mutate the original list—it never does by itself. - Using
filterwith a huge lambda when a list comprehension would be clearer to the next reader. - Misunderstanding
filter(None, ...)as “removeNoneonly”—it removes all falsy values. - Iterating the same
filterobject twice: the iterator is exhausted after the first pass; callfilteragain or storelist(...)if you need multiple walks. - Overly complex lambdas—switch to a named
deffor readability.
def is_positive(x):
return x > 0
nums = [-1, 2, 3]
f = filter(is_positive, nums)
print(f) # shows a filter object, not the values
print(list(f))
# filter(is_positive(), nums) # wrong: TypeError—calls the function before filter runsYou should see a line starting with <filter object and then [2, 3].
nums = [1, 2, 3]
f = filter(lambda x: x % 2 == 0, nums)
print(list(f))
print(list(f)) # already exhaustedYou should see [2] then [].
Python filter() quick reference table
| Need | Pattern |
|---|---|
| Basic filter | filter(pred, iterable) |
| Materialize | list(filter(...)) |
| Keep truthy only | filter(None, iterable) |
| Dict by value | dict(filter(lambda kv: ..., d.items())) |
| Lazy + transform | map(fn, filter(pred, iterable)) |
| Readable inline | [x for x in items if cond] |
Summary
filter(function, iterable) returns a Python 3 iterator that yields items where function(item) is true, or where the item is truthy when function is None. Convert with list() when you need a list, reuse predicates as normal functions when logic grows, and reach for comprehensions when the condition is short and clarity beats laziness. Remember iterators are single-use unless you rebuild them.

