How can I use list comprehension with an if/else statement in Python?

How can I use list comprehension with an if/else statement in Python?

I want to convert the following for-loop with an if/else condition into a list comprehension:

results = []
for x in xs:
    results.append(f(x) if x is not None else '')

It should return '' if x is None, and f(x) otherwise. I tried:

[f(x) for x in xs if x is not None else '']

but it gives a SyntaxError. What is the correct syntax?

You can definitely achieve this with list comprehension by adjusting the order:

[f(x) if x is not None else '' for x in xs]

In general, the syntax is:

[f(x) if condition else g(x) for x in sequence]

For list comprehensions with only if conditions:

[f(x) for x in sequence if condition]

Note that using a conditional expression inside a list comprehension is different from the if condition used for filtering elements. The conditional expression, which is not part of the comprehension syntax, allows you to choose between two values based on a condition. This is similar to the ternary operator ?: in other languages. For example:

value = 123
print(value, 'is', 'even' if value % 2 == 0 else 'odd')

The specific problem has already been addressed in previous answers, so I will focus on the general concept of using conditionals inside list comprehensions.

Here are some examples that demonstrate how to write conditionals within a list comprehension:

X = [1.5, 2.3, 4.4, 5.4, 'n', 1.5, 5.1, 'a']  # Original list

# Extract non-strings from X into a new list
X_non_str = [el for el in X if not isinstance(el, str)]  # When using only 'if', place 'for' at the beginning

# Replace all strings in X with 'b', while preserving everything else
X_str_changed = ['b' if isinstance(el, str) else el for el in X]  # When using 'if' and 'else', place 'for' at the end

In the first list comprehension for X_non_str, the order is:

expression for item in iterable if condition

In the second list comprehension for X_str_changed, the order is:

expression1 if condition else expression2 for item in iterable

It can be tricky to remember that expression1 must come before if and expression2 must come after else. This structure resembles natural language, for example, “I want to stay inside if it rains, else I want to go outside.”

In plain English, the two types of list comprehensions mentioned above could be described as:

With only if:

extract_apple for apple in apple_box if apple_is_ripe

And with if/else:

mark_apple if apple_is_ripe else leave_it_unmarked for apple in apple_box

Here’s one approach:

def change(x):
    if x is not None:
        return f(x)
    else:
        return ''

You can then use this function within a list comprehension:

result = [change(x) for x in xs]

Alternatively, you can use the map function:

result = map(change, xs)

Or you can use an inline lambda function:

result = [f(x) if x is not None else '' for x in xs]