List Comprehensions

RoadmapsPython

Overview

A list comprehension is an expression that builds a new list by transforming and optionally filtering items from an iterable, all in a single line. The syntax is: [expression for item in iterable] [expression for item in iterable if condition] Python evaluates it by iterating over the iterable, optionally testing the condition, and collecting the `expression` result into a new `list`. It is exactly equivalent to writing a `for` loop that calls `.append()` on an empty `list`, but more concise and often faster because the append is handled internally by the interpreter. Concrete examples: status_codes = [200, 404, 200, 500, 301] ok_codes = [code for code in status_codes if code == 200] # ok_codes -> [200, 200] usernames = ['alice', 'bob', 'carol'] upper_names = [name.upper() for name in usernames] # upper_names -> ['ALICE', 'BOB', 'CAROL'] prices = [9.99, 24.50, 3.75, 49.00] discounted = [round(p * 0.9, 2) for p in prices] # discounted -> [9.0, 22.05, 3.38, 44.1] You can call any function in the `expression` part — `str.upper()`, `round()`, or your own helpers. The `if` clause is optional; without it, every item is included. Think of a list comprehension as a factory conveyor belt: items roll in from the iterable, a filter gate (the `if` clause) drops items that fail the test, and each surviving item is reshaped by the `expression` before landing in the output bin. Back in Python, the "conveyor belt" is the `for` clause, the "gate" is the optional `if` clause, and the "reshaping step" is the `expression`. Readability rule: keep comprehensions to one readable line. If you need nested loops, multiple conditions, or side effects, use a regular `for` loop instead. matrix = [[1, 2], [3, 4]] # Trap: order is outer-first, matching normal loops, not inner-first flat = [x for row in matrix for x in row] When dealing with nested comprehensions, the loop order can be extremely counter-intuitive. This is covered fully in nested-comprehensions.

List comprehensions replace the repetitive pattern of creating an empty `list`, looping, and calling `.append()` — the most common list-building pattern in Python. They make data-transformation code shorter, more declarative, and often faster. Mastering them is essential because they appear everywhere in production Python code.

Where used: Transforming API response lists, Filtering database query results, Building FastAPI response payloads, Data pipeline transformations

Why learn this

Code walkthrough

status_codes = [200, 404, 200, 500, 301]

# Equivalent for-loop
ok_loop = []
for code in status_codes:
    if code == 200:
        ok_loop.append(code)

# Same result with a comprehension
ok_comp = [code for code in status_codes if code == 200]

print('loop:', ok_loop)
print('comp:', ok_comp)

Focus: Both produce the same `list` — the comprehension collapses the loop, condition, and `.append()` into one expression.

Aha moment

tags = ['python', 'fastapi', 'sql', 'python', 'docker']
unique_sorted = sorted([t for t in tags if t != 'sql'])
original = tags
print('result:', unique_sorted)
print('original:', original)
print('same object?', unique_sorted is original)

Prediction: Does the comprehension modify the original `tags` list?

Common guess: Yes, it removes 'sql' from tags

A comprehension always builds a brand-new `list` — it never mutates the source iterable. The original `list` is untouched, and `is` confirms they are different objects.

Common mistakes

Glossary

iterable
Any collection or data structure in Python that you can loop through one item at a time, like a list or a string, e.g. `for x in [1, 2, 3]`.
declarative
A style of programming where you describe what you want the result to be, rather than writing the step-by-step instructions on how to get it, e.g. `[x*2 for x in nums]` instead of a manual append loop.

Recall questions

Understanding checks

What is the output of this list comprehension?

['alice', 'carol']

The `if n.isupper()` clause filters out `'bob'`. The remaining strings `'ALICE'` and `'CAROL'` are passed to `n.lower()`, producing `'alice'` and `'carol'`.

Why does this comprehension result in a syntax error?

A filtering `if` clause must go after the `for` clause, not before it. Moving `if x > 1` to after `for x in nums` fixes the error: `[x * 2 for x in nums if x > 1]`.

A filtering `if` must go *after* the `for` clause (`[x * 2 for x in nums if x > 1]`). Putting it before the `for` is only valid when using an `if-else` ternary expression.

Practice tasks

Filter and extract usernames

The current code correctly filters for active users, but it only extracts their IDs. Modify the list comprehension so that it extracts the `username` (as a string) instead of the `id`.

Challenge

Transform database rows into API response dicts

You have a `list` of `dict`s representing database rows with keys `'id'`, `'email'`, `'role'`, and `'is_active'`. Using list comprehensions, produce a `list` of response `dict`s containing only `'id'` and `'email'` for users whose `'role'` is `'admin'` and who are active.

Continue learning

Previous: Lists: indexing, slicing, methods

Previous: for and while loops

Previous: if/elif/else and Python truthiness

Next: Dictionary and set comprehensions

Next: Nested comprehensions

Next: Generator expressions vs list comprehensions

Return to Python Roadmap