Back to Blog
Python

Python List Comprehension with If Condition

Use if conditions in Python list comprehensions to filter items, combine conditions, and choose values with if-else. Includes nested examples and readability tips.

list comprehensionconditional filteringpython syntaxgenerator expressionsreadability
Illustration of Python list comprehension with a conditional filter selecting elements from a list.

A list comprehension with an if clause lets you build a new list from an existing iterable while filtering out unwanted items. It combines iteration and filtering into one expression, which usually reads more directly than an explicit for loop with temporary variables.

Basic Syntax: Filtering with if

The simplest form places the if condition after the for clause:

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

The expression n is evaluated for each item in numbers, but only when the condition n % 2 == 0 is true. This is equivalent to:

even = [] for n in numbers: if n % 2 == 0: even.append(n)

The comprehension version is shorter and keeps the logic visible. In CPython, comprehensions are compiled to a dedicated code object with optimized append handling, so they often avoid overhead from an explicit loop. The actual difference depends on the data and condition.

Using if-else Inside the Expression

The if keyword can also appear inside the expression part, before the for clause, to choose between two values. This is not a filter but a conditional mapping:

labels = ["even" if n % 2 == 0 else "odd" for n in range(1, 6)]

Here, every item from the iterable is included, but the output value changes based on the condition. The syntax is value_if_true if condition else value_if_false followed by the for clause. This is different from the filter form, which uses if condition without else and includes only items that satisfy the condition.

Combining Multiple Conditions

You can chain multiple conditions using and, or, and parentheses. For example, to select numbers that are divisible by 3 and greater than 10:

values = [12, 15, 18, 21, 24, 27, 30] selected = [v for v in values if v % 3 == 0 and v > 10]

For more complex logic, consider extracting the condition into a helper function to keep the comprehension readable:

def is_valid(v): return v % 3 == 0 and v > 10 selected = [v for v in values if is_valid(v)]

This also makes the condition reusable and easier to unit test.

Nested List Comprehensions with Conditions

When the iterable contains nested values, the if condition can be placed at different positions. The order of for clauses follows the nesting depth: outer loops first, then inner loops. A condition at the end applies to the innermost variable:

matrix = [[1, -2, 3], [-4, 5, -6]] positives = [num for row in matrix for num in row if num > 0]

You can also test the outer value before descending into the inner loop. For instance, to skip a None row while flattening a matrix:

matrix = [[1, 2], None, [3, 4]] flattened = [item for row in matrix if row is not None for item in row]

The if is evaluated for each outer element, and only when it passes does the inner loop execute. Placing a condition between for clauses is valid Python, but read it carefully: it can be less obvious than writing a nested loop.

Performance and Readability Tradeoffs

List comprehensions create the entire list in memory at once. If you only need to iterate over the filtered results once, a generator expression with the same syntax uses less memory:

even_gen = (n for n in numbers if n % 2 == 0)

The generator yields items lazily, so it avoids allocating a full list. This matters when the source iterable is large or when the result is consumed only once.

Readability is the main reason to be cautious with long comprehensions. A comprehension that spans multiple lines or contains several conditions is harder to read than a well-named loop. As a rule, if the comprehension requires more than one if condition or nested loops, consider refactoring into a regular loop or a helper function.

Common Mistakes and Edge Cases

One frequent mistake is placing the if in the wrong position. The filter if must come after the for clause, not before it. Writing [if x > 0 for x in items] is a syntax error. The conditional expression form must include else; omitting it causes a SyntaxError because the parser expects an expression.

Another edge case is using a condition that raises an exception for certain items. For example, checking if item["key"] on a list of dictionaries where some dictionaries lack that key will raise KeyError. The condition is evaluated eagerly for each item, so you must handle such cases explicitly, either with a try block inside a helper or by using a safer condition like if item.get("key").

When you need to filter and transform in one step, you can combine the conditional expression and the filter:

values = [1, -2, 3, -4, 5] result = [abs(v) if v < 0 else v for v in values if v != 0]

This applies a transformation to negative numbers while excluding zeros. The order matters: the expression is evaluated only for items that pass the filter.

When to Use Alternatives

In Python 3, the filter() built-in can filter an iterable, but it returns an iterator and requires a function object. A list comprehension is often more readable because the condition is written inline. For simple cases, the comprehension is preferred by most Python developers.

If you need to apply a condition that depends on the index, use enumerate():

items = ["a", "b", "c", "d"] selected = [item for idx, item in enumerate(items) if idx % 2 == 0]

This gives you both the value and its position, which a plain for clause cannot provide.

Finally, remember that list comprehensions are not always the best choice for side effects. If you are calling a function for its side effect and discarding the result, a loop is clearer:

# Avoid [print(x) for x in items] # Prefer for x in items: print(x)

The comprehension creates a list of None values that is immediately discarded, which is wasteful and obscures intent.

How to Use If Conditions in Python List Comprehensions | RYUSLOG DEV