Question
Python List Comprehension with if/else: Conditional Expressions
Question
How can I convert this Python for loop, which uses an if/else expression, into a list comprehension?
results = []
for x in xs:
results.append(f(x) if x is not None else "")
The result should contain "" when x is None; otherwise, it should contain f(x). I tried the following, but it raises a SyntaxError:
[f(x) for x in xs if x is not None else ""]
What is the correct list-comprehension syntax?
Short Answer
You will learn that Python list comprehensions support two different uses of if: a trailing if filters items, while value_if_true if condition else value_if_false chooses the value to produce. You will also see how to translate loops safely and readably.
Concept
A list comprehension creates a new list by evaluating an expression once for each item in an iterable.
Its basic shape is:
[expression for item in iterable]
To choose between two output values, put Python's conditional expression in the expression position:
[value_if_true if condition else value_if_false for item in iterable]
For this case, the correct code is:
results = [f(x) if x is not None else "" for x in xs]
The important distinction is that a list comprehension has two forms involving if:
expression for x in xs if conditionmeans include only matching items.true_value if condition else false_value for x in xsmeans include every item, but select its output value.
This matters because filtering out None values changes the list length, while replacing each with preserves the original positions and length.
Mental Model
Think of a list comprehension as a conveyor belt.
- The
for x in xspart puts every input item onto the belt. - The expression at the beginning decides what gets placed into the output box.
- A trailing
ifis a gate: items that fail the condition are removed entirely. - An
if/elseexpression at the beginning is a sorter: every item stays on the belt, but it is converted into one of two possible values.
Here, None should not be removed. It should be converted to an empty string, so use the sorter form:
f(x) if x is not None else ""
Syntax and Examples
The syntax for a conditional expression inside a list comprehension is:
[result_when_true if condition else result_when_false for item in iterable]
Example:
numbers = [4, -2, 0, 7]
labels = ["positive" if n > 0 else "not positive" for n in numbers]
print(labels)
# ['positive', 'not positive', 'not positive', 'positive']
The expression is evaluated for every number:
- If
n > 0is true, the result is"positive". - Otherwise, the result is
"not positive".
For the original pattern:
def f(value):
return value.upper()
xs = ["cat", None, "dog"]
results = [f(x) if x x xs]
(results)
Step by Step Execution
Consider this code:
xs = ["a", None, "b"]
results = [x.upper() if x is not None else "" for x in xs]
Python processes the list from left to right:
-
xis"a".x is not Noneis true.- Evaluate
x.upper(). - Add
"A"toresults.
-
xisNone.x is not Noneis false.- Evaluate the
elsebranch,"". - Add
""toresults.
Real World Use Cases
Conditional expressions in list comprehensions are useful when an output list must preserve one result per input item.
-
Cleaning imported CSV data: Replace missing names represented by
Nonewith an empty string.display_names = [name.strip() if name is not None else "" for name in names] -
Formatting optional API fields: Use a fallback label when a value is absent.
labels = [item["title"] if item["title"] is not None else "Untitled" for item in items] -
Preparing UI values: Convert optional values into strings that form controls can display.
form_values = [str(value) if value is not None else "" for value values]
Real Codebase Usage
In production code, use a conditional list comprehension when the transformation is short and remains easy to read:
normalized = [value.strip() if value is not None else "" for value in raw_values]
Developers commonly combine this with validation. For example, a guard clause may reject invalid input before a comprehension performs normal transformations:
def normalize_tags(tags):
if tags is None:
return []
return [tag.strip().lower() for tag in tags if tag and tag.strip()]
Notice that this example uses a trailing if intentionally: blank tags are meant to be omitted.
When the conditional logic becomes complicated, prefer a named helper function or a regular loop. It is easier to test and debug:
def display_value(value):
if value is None:
format_value(value)
results = [display_value(x) x xs]
Common Mistakes
Putting else after the trailing filter
This is invalid syntax:
# SyntaxError
[f(x) for x in xs if x is not None else ""]
The if after for x in xs is a filter clause. A filter has no else because it only decides whether to include an item.
Use a conditional expression before for instead:
[f(x) if x is not None else "" for x in xs]
Filtering when you meant to preserve positions
This code removes None values entirely:
[f(x) for x in xs if x ]
Comparisons
| Pattern | Syntax | What it does | Output length |
|---|---|---|---|
| Simple mapping | [f(x) for x in xs] | Transforms every item | Same as input |
| Conditional mapping | [f(x) if x is not None else "" for x in xs] | Transforms or substitutes every item | Same as input |
| Filtering | [f(x) for x in xs if x is not None] | Transforms only items that pass | Same or shorter |
| Filtering and mapping | [f(x) for x in xs if is_valid(x)] | Omits invalid items, transforms valid ones | Same or shorter |
| Regular loop | for x in xs: ... |
Cheat Sheet
# Map every item
[f(x) for x in xs]
# Filter items: omit values that fail the condition
[f(x) for x in xs if condition(x)]
# Choose one of two output values for every item
[true_value if condition(x) else false_value for x in xs]
# Original pattern
[f(x) if x is not None else "" for x in xs]
Rules:
- Put the output expression first.
- Put
for item in iterablenext. - A trailing
ifis a filter and cannot haveelse. - An
if/elseexpression must include both branches. - Use
is Noneandis not Nonewhen checking specifically forNone. - Conditional mapping keeps one output item per input item; filtering can shorten the list.
FAQ
Why does if x is not None else "" cause a SyntaxError after for x in xs?
After for x in xs, Python expects an optional filter condition. A filter only includes or excludes an item, so else is not allowed there.
What is the correct Python syntax for if/else in a list comprehension?
Put the conditional expression before the for clause:
[true_value if condition else false_value for item in iterable]
Does a conditional list comprehension remove None values?
Not when you use if/else in the expression. It produces a replacement value for each None. Use a trailing if to remove them.
Should I use x is not None or if x?
Use x is not None when 0, False, or empty strings are legitimate values that must not be treated as missing.
Mini Project
Description
Build a small data-cleaning function for optional customer names. Imported data may contain None, extra whitespace, or normal strings. The project demonstrates conditional mapping: each input should produce exactly one cleaned output value.
Goal
Create a function that converts missing names to "" and trims whitespace from present names.
Requirements
- Create a function named
clean_namesthat accepts a list of names. - Return a new list without changing the original list.
- Convert each
Nonevalue to an empty string. - Remove leading and trailing whitespace from each non-
Nonename. - Preserve the input order and the number of items.
Keep learning
Related questions
@staticmethod vs @classmethod in Python Explained
Learn the difference between @staticmethod and @classmethod in Python with clear examples, use cases, mistakes, and a mini project.
Add Rows to a Pandas DataFrame in Python
Learn how to add rows to a Pandas DataFrame, why repeated row appends are slow, and when to use loc, concat, or record lists.
Call a Function by Name in a Python Module
Learn how to call a function by name in a Python module using strings, getattr, and safe patterns for dynamic function dispatch.