How to Filter a List in Python

Filtering a list means keeping only the items that match a rule.

For example, you might want to:

  • keep only even numbers
  • keep only names longer than 4 letters
  • remove empty strings
  • keep only dictionaries where age >= 18

In Python, the most common way to do this is with a list comprehension. You can also use the built-in filter() function.

Quick answer

numbers = [1, 2, 3, 4, 5, 6]
even_numbers = [n for n in numbers if n % 2 == 0]
print(even_numbers)
# Output: [2, 4, 6]

Use a list comprehension when you want to build a new list by keeping only items that match a condition.

What filtering a list means

Filtering means:

  • keeping some items
  • leaving out other items
  • creating a new list based on a condition

For example, if you only want numbers greater than 10, you check each item and keep the ones that match.

In most cases, the original list stays unchanged.

numbers = [5, 12, 8, 20]
filtered = [n for n in numbers if n > 10]

print(numbers)
print(filtered)

Output:

[5, 12, 8, 20]
[12, 20]

If you need a refresher on lists first, see Python lists explained for beginners.

Filter a list with a list comprehension

A list comprehension is the most common Python way to filter a list.

The basic pattern is:

[item for item in items if condition]

Here:

  • item is the current value
  • items is the original list
  • if condition decides whether the item is kept

Example: keep only even numbers.

numbers = [1, 2, 3, 4, 5, 6]
even_numbers = [n for n in numbers if n % 2 == 0]

print(even_numbers)

Output:

[2, 4, 6]

How this works

Python checks each number one by one:

  • 1 % 2 == 0False → leave it out
  • 2 % 2 == 0True → keep it
  • 3 % 2 == 0False → leave it out

If you want more practice with this syntax, see how to use list comprehensions in Python.

Filter strings from a list

You can also filter text values.

Keep names longer than 4 letters

names = ["Sam", "Olivia", "Liam", "Emily", "Noah"]
long_names = [name for name in names if len(name) > 4]

print(long_names)

Output:

['Olivia', 'Emily']

The condition is len(name) > 4, so only names with more than 4 letters are kept.

Keep words starting with a specific letter

words = ["apple", "banana", "avocado", "grape"]
a_words = [word for word in words if word.startswith("a")]

print(a_words)

Output:

['apple', 'avocado']

Here, startswith("a") checks each word one by one.

Filter a list with filter()

Python also has a built-in function called filter().

It needs:

  • a function that returns True or False
  • a list or other iterable to check

Example:

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

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

result = filter(is_even, numbers)
even_numbers = list(result)

print(even_numbers)

Output:

[2, 4, 6]

Important: filter() does not return a list

filter() returns a filter object, not a normal list.

That is why beginners usually wrap it with list():

numbers = [1, 2, 3, 4]
result = filter(lambda n: n > 2, numbers)

print(result)
print(list(result))

Possible output:

<filter object at 0x...>
[3, 4]

For simple cases, list comprehensions are usually easier to read. If you want to learn more about this built-in function, see the Python filter() function explained.

Filter out empty values

A very common task is removing empty strings.

items = ["", "apple", "", "banana", "orange", ""]
filtered = [item for item in items if item]

print(filtered)

Output:

['apple', 'banana', 'orange']

Why if item works

In Python:

  • an empty string "" is treated as False
  • a non-empty string like "apple" is treated as True

So if item keeps only the non-empty values.

You can do the same with filter():

items = ["", "apple", "", "banana"]
filtered = list(filter(None, items))

print(filtered)

Output:

['apple', 'banana']

This is short and useful, but the list comprehension version is often easier for beginners to understand.

Filter a list of dictionaries

Filtering a list of dictionaries is also common.

Example: keep only people who are age 18 or older.

people = [
    {"name": "Anna", "age": 17},
    {"name": "Ben", "age": 21},
    {"name": "Cara", "age": 18}
]

adults = [person for person in people if person["age"] >= 18]

print(adults)

Output:

[{'name': 'Ben', 'age': 21}, {'name': 'Cara', 'age': 18}]

How it works

Inside the condition, person["age"] gets the age value from each dictionary.

If that value is 18 or more, the dictionary is kept.

Watch out for missing keys

This will fail if one dictionary does not have an "age" key.

people = [
    {"name": "Anna", "age": 17},
    {"name": "Ben"},
    {"name": "Cara", "age": 18}
]

adults = [person for person in people if person["age"] >= 18]

This raises a KeyError.

A safer version uses .get():

people = [
    {"name": "Anna", "age": 17},
    {"name": "Ben"},
    {"name": "Cara", "age": 18}
]

adults = [person for person in people if person.get("age", 0) >= 18]

print(adults)

Output:

[{'name': 'Cara', 'age': 18}]

If you run into this problem, see KeyError in Python: causes and fixes.

Common beginner mistakes when filtering

Here are some common problems beginners run into.

Expecting the original list to change

Filtering usually creates a new list.

numbers = [1, 2, 3, 4]
filtered = [n for n in numbers if n > 2]

print(numbers)   # original list
print(filtered)  # new filtered list

Using = instead of ==

Use == when comparing values.

Wrong:

# This is invalid Python
# [n for n in numbers if n = 2]

Correct:

numbers = [1, 2, 3, 2]
twos = [n for n in numbers if n == 2]

print(twos)

Output:

[2, 2]

Forgetting that filter() returns an iterable

This can be confusing:

numbers = [1, 2, 3, 4]
result = filter(lambda n: n > 2, numbers)

print(type(result))

Output:

<class 'filter'>

If you want a list, convert it:

filtered = list(result)
print(filtered)

Writing a condition that does not behave as expected

Sometimes the condition is not checking what you think it is.

For example:

numbers = [0, 1, 2, 3]
filtered = [n for n in numbers if n]

print(filtered)

Output:

[1, 2, 3]

This removes 0 because 0 is treated as False in Python.

Removing items from a list while looping over it

This often causes skipped values or unexpected results.

Avoid this:

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

for n in numbers:
    if n % 2 == 0:
        numbers.remove(n)

print(numbers)

Instead, create a new filtered list:

numbers = [1, 2, 3, 4, 5]
odd_numbers = [n for n in numbers if n % 2 != 0]

print(odd_numbers)

If you are practicing list loops, see how to loop through a list in Python.

When to use each approach

Use a list comprehension when:

  • the condition is simple
  • you want the result as a list
  • you want code that is easy to read

Use filter() when:

  • you already have a function that checks each item
  • you want to reuse that function
  • the code reads clearly with that function

In general:

  • choose the version that is easiest to understand
  • avoid very complex one-line conditions
  • prefer readability over clever code

FAQ

Does filtering change the original list?

Usually no. Most filtering examples create a new list and leave the original list unchanged.

Should I use list comprehension or filter()?

For beginners, list comprehensions are usually easier to read and more common in everyday Python code.

Can I filter numbers, strings, and dictionaries?

Yes. You can filter any list as long as you can write a condition that checks each item.

Why does filter() not print a normal list?

Because filter() returns a filter object. Wrap it in list() if you want a list.

See also