Python filter() Function

Learn Python filter() function with simple examples. Filter lists, strings, dictionaries, and objects using normal functions, lambda functions, filter(None), and list comprehension alternatives.

Published

Updated

Read time 6 min read

Reviewed byDeepak Prasad

Python filter() Function

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.

python
numbers = [1, 2, 3, 4, 5, 6]

even_numbers = filter(lambda x: x % 2 == 0, numbers)

print(list(even_numbers))
Output

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

text
filter(function, iterable)
  • function: a callable taking one argument, or None (see filter(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).

python
nums = [1, 2, 3]
positive = filter(lambda x: x > 0, nums)
print(list(positive))
Output

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.

python
def is_even(n):
    return n % 2 == 0


numbers = [1, 2, 3, 4, 5, 6]
print(list(filter(is_even, numbers)))
Output

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.

python
numbers = [1, 2, 3, 4, 5, 6]
print(list(filter(lambda x: x % 2 == 1, numbers)))
Output

You should see [1, 3, 5].


Filter strings using filter()

Strings are iterable over characters. Here we keep only ASCII letters.

python
text = "a1b2c"
print("".join(filter(str.isalpha, text)))
Output

You should see abc.


Filter a dictionary using filter()

dict.items() yields (key, value) pairs; filter them, then pass the iterator to dict(...).

python
scores = {"Alice": 85, "Bob": 40, "Charlie": 72}

passed = dict(filter(lambda item: item[1] >= 50, scores.items()))

print(passed)
Output

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.

python
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])
Output

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.

python
values = [0, 1, "", "hello", None, [], [1, 2], False, True]

result = list(filter(None, values))

print(result)
Output

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.

python
numbers = [1, 2, 3, 4, 5, 6]

even_numbers = [x for x in numbers if x % 2 == 0]

print(even_numbers)
Output

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.

python
nums = [1, 2, 3, 4]
labels = list(map(str, filter(lambda x: x % 2 == 0, nums)))
print(labels)
Output

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 with list() or iterating in a loop.
  • Writing filter(some_func(), iterable) instead of filter(some_func, iterable)—you must pass the function object, not call it in place unless it returns a callable.
  • Expecting filter to mutate the original list—it never does by itself.
  • Using filter with a huge lambda when a list comprehension would be clearer to the next reader.
  • Misunderstanding filter(None, ...) as “remove None only”—it removes all falsy values.
  • Iterating the same filter object twice: the iterator is exhausted after the first pass; call filter again or store list(...) if you need multiple walks.
  • Overly complex lambdas—switch to a named def for readability.
python
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 runs
Output

You should see a line starting with <filter object and then [2, 3].

python
nums = [1, 2, 3]
f = filter(lambda x: x % 2 == 0, nums)
print(list(f))
print(list(f))  # already exhausted
Output

You 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.


References


Frequently Asked Questions

1. What does Python filter() return?

In Python 3, filter() returns an iterator (a filter object); consume it in a loop, pass it to list(), or walk it once—materialize with list() when you need all values in memory.

2. What is the difference between filter() and list comprehension?

filter() shines when you already have a named predicate function or want a lazy iterator; list comprehensions are often clearer for short inline conditions on simple data.

3. What does filter(None, iterable) do?

With function set to None, filter uses the identity and drops items that are false in a boolean context (falsy values such as 0, empty containers, None, False).

4. Does filter() change the original list?

No—it builds a new iterator over the iterable; the source list or other collection is left unchanged unless your predicate mutates it as a side effect.

5. Why is my second list(filter(...)) empty?

filter iterators are single-pass; after you exhaust them once, you must call filter() again or store the list result if you need to iterate multiple times.
Bashir Alam

Data Analyst and Machine Learning Engineer

Computer Science graduate from the University of Central Asia, currently employed as a full-time Machine Learning Engineer at uExel. His expertise lies in OCR, text extraction, data preprocessing, and …