Back to Blog
Python

Python List Comprehension with If Condition

python list comprehension if condition: Learn how to use if conditions in Python list comprehensions to filter items, combine conditions, and write concise readable code.

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

When you need to build a new list from an existing iterable while filtering out certain items, the python list comprehension if condition pattern is one of the most direct tools available. A list comprehension with an if clause lets you combine iteration and filtering into a single expression, avoiding explicit for loops and 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 one line. It also runs at c-level speed for many built-in iterables, though the actual performance difference depends on the size of the data and the complexity of the 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 omits the else and only includes 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 working with nested iterables, you can place a conditional inside the inner comprehension. For instance, flattening a matrix while skipping empty rows:

matrix = [[1, 2], [], [3, 4], [5]] flattened = [item for row in matrix if row for item in row]

The if row filters out empty lists before the inner for runs. Without that guard, the inner loop would produce no items for an empty row, but the comprehension would still work. The condition is evaluated for each outer element, and only if it passes does the inner loop execute.

You can also apply a condition to the inner items:

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

This filters at the innermost level. The order of for clauses follows the nesting depth: outer loops first, then inner loops, with the final if applying to the innermost variable.

Performance and Readability Tradeoffs

List comprehensions are generally faster than manual for loops because the loop runs in C and the append operation is optimized. However, they 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

The filter() built-in can also filter a sequence, 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.

python list comprehension if condition: Practical Usage and | RYUSLOG DEV