List, Set & Dictionary Comprehensions
Learn the compact comprehension syntax for building lists, sets, and dictionaries in a single readable line of code.
Introduction
A huge amount of everyday Python code follows the same simple pattern: start with an empty collection, loop over some data, and add a transformed or filtered value on each pass. Comprehensions let you express that entire pattern in a single, readable line.
Comprehensions exist for lists, sets, and dictionaries, and they all share the same underlying structure. Once you learn one, the others feel almost identical.
- The basic list comprehension syntax.
- How to filter items using an if condition inside a comprehension.
- How to write nested comprehensions, such as flattening a 2D list.
- How to write dictionary and set comprehensions.
- When a comprehension improves readability, and when a regular loop is the better choice.
Basic List Comprehension Syntax
A list comprehension builds a new list by applying an expression to every item from an iterable. The basic shape is [expression for item in iterable].
numbers = [1, 2, 3, 4, 5]
# The traditional loop way
squares = []
for n in numbers:
squares.append(n * n)
print(squares)
# The comprehension way
squares_comp = [n * n for n in numbers]
print(squares_comp)[1, 4, 9, 16, 25]
[1, 4, 9, 16, 25]Both versions produce the exact same result. The comprehension simply reads as "give me n * n, for every n in numbers" — the loop, the append, and the empty list are all folded into that one line.
expression
What gets computed and added to the new list for each item, e.g. n * n.
for item in iterable
The loop that walks through the source data, e.g. for n in numbers.
Adding a Condition (Filtering)
You can filter which items are included by adding an if clause at the end: [expression for item in iterable if condition]. Only items where the condition is True get included in the result.
numbers = range(1, 11)
even_numbers = [n for n in numbers if n % 2 == 0]
print(even_numbers)[2, 4, 6, 8, 10]words = ["hi", "hello", "hey", "greetings", "yo"]
long_words_upper = [word.upper() for word in words if len(word) > 3]
print(long_words_upper)['HELLO', 'GREETINGS']The if condition here is evaluated for each word first; only words that pass the length check move on to have .upper() applied.
Nested Comprehensions
You can nest comprehensions to work with nested data, like a list of lists. A common example is flattening a 2D grid into a single flat list.
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [number for row in matrix for number in row]
print(flattened)[1, 2, 3, 4, 5, 6, 7, 8, 9]Reading it in plain English helps: "for each row in matrix, for each number in that row, take the number." The two for clauses are written in the same left-to-right order as the equivalent nested loop.
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = []
for row in matrix:
for number in row:
flattened.append(number)
print(flattened)[1, 2, 3, 4, 5, 6, 7, 8, 9]In a nested comprehension, the for clauses read left to right in the same order you would write them as nested for loops.
Dictionary Comprehensions
A dictionary comprehension builds a new dictionary using the shape {key_expression: value_expression for item in iterable}, using curly braces and a colon instead of square brackets.
names = ["Alice", "Bob", "Charlie"]
name_lengths = {name: len(name) for name in names}
print(name_lengths){'Alice': 5, 'Bob': 3, 'Charlie': 7}prices = {"apple": 40, "bread": 60, "milk": 25, "cheese": 90}
affordable = {item: cost for item, cost in prices.items() if cost < 50}
print(affordable){'apple': 40, 'milk': 25}Set Comprehensions
A set comprehension looks just like a list comprehension, but uses curly braces {} instead of square brackets, and — like every set — automatically removes duplicate values.
words = ["apple", "Banana", "APPLE", "banana", "Cherry"]
unique_lowercase = {word.lower() for word in words}
print(unique_lowercase){'apple', 'banana', 'cherry'}Even though the original list has five entries with mixed casing, the set comprehension normalizes each word to lowercase and keeps only the unique results.
| Type | Syntax | Result |
|---|---|---|
| List | [x for x in iterable] | A list, may contain duplicates, preserves order. |
| Set | {x for x in iterable} | A set, duplicates automatically removed, unordered. |
| Dict | {k: v for x in iterable} | A dictionary of key-value pairs. |
Readability Tradeoff
Comprehensions are concise, but concise is not always the same as clear. A short comprehension with one transformation and one filter is usually easier to read than the equivalent loop. A comprehension packed with multiple conditions and nested loops can quickly become harder to read than a plain for loop.
numbers = range(20)
squares_of_evens = [n * n for n in numbers if n % 2 == 0]
print(squares_of_evens)[0, 4, 16, 36, 64, 100, 144, 196, 256, 324]data = [[1, -2, 3], [4, 5, -6], [-7, 8, 9]]
# Hard to read in one line:
result = [x * 2 for row in data for x in row if x > 0 if x % 2 != 0]
print(result)
# Clearer as a regular loop:
result_loop = []
for row in data:
for x in row:
if x > 0 and x % 2 != 0:
result_loop.append(x * 2)
print(result_loop)[2, 6, 18]
[2, 6, 18]If you cannot read a comprehension out loud in one comfortable sentence, it is probably time to rewrite it as a regular for loop instead.
Common Mistakes
- Using square brackets [] when you meant to build a set or dictionary — {} is required for those.
- Writing overly complex comprehensions with several nested loops and conditions, which hurts readability more than it helps.
- Forgetting that dict comprehensions need a key:value pair, not just a single expression.
- Assuming set comprehensions preserve order — sets are unordered, so the printed order may not match the input order.
- Overusing comprehensions for side effects (like printing) instead of building a new collection — a regular for loop is clearer for that.
Best Practices
- Use a comprehension when the logic is a simple transform, filter, or both — one expression, one loop, at most one condition.
- Switch to a regular for loop once you need multiple conditions, side effects, or several nested loops.
- Use dict and set comprehensions instead of manually building them with a loop and .update() or .add().
- Give the loop variable a clear name, even in a comprehension — n or number is clearer than x in most contexts.
- Break a long comprehension across multiple lines using parentheses if it improves readability.
Frequently Asked Questions
Are comprehensions faster than a regular for loop?
Comprehensions are often slightly faster than an equivalent for loop with .append(), because they are optimized internally by the Python interpreter, but the main benefit is usually readability, not raw speed.
Can I use if/else inside a comprehension?
Yes, but the syntax is different from a filtering if. A conditional expression goes before the for clause: [value_if_true if condition else value_if_false for item in iterable].
What is the difference between a list comprehension and a generator expression?
A list comprehension [x for x in ...] builds the entire list immediately in memory. A generator expression (x for x in ...) produces values lazily, one at a time, as covered in the Generators lesson.
Can I nest a dict comprehension inside a list comprehension?
Yes, comprehensions of different types can be nested inside each other, but doing so often hurts readability — it is usually clearer to break the logic into a helper function or a regular loop.
Do set and dict comprehensions support filtering with if, like list comprehensions?
Yes, all three comprehension types support the same optional if condition at the end, using identical syntax.
Key Takeaways
- A list comprehension uses the form [expression for item in iterable] to build a new list.
- Adding if condition at the end filters which items are included.
- Nested comprehensions can flatten nested structures like a list of lists, using multiple for clauses.
- Dict comprehensions use {key: value for item in iterable}; set comprehensions use {expression for item in iterable}.
- Comprehensions improve readability for simple cases, but a regular for loop is often clearer once logic becomes complex.
Summary
Comprehensions give you a compact, expressive way to build lists, sets, and dictionaries directly from an iterable, optionally filtering and transforming values along the way. They shine for simple, single-purpose transformations, but readability should always come before cleverness.
In this lesson, you learned the syntax for list, dict, and set comprehensions, how to filter with if, how to nest comprehensions to flatten data, and when a plain for loop communicates your intent more clearly. Next, you will learn about regular expressions for powerful text pattern matching.
- You can write list, set, and dictionary comprehensions.
- You can filter and transform data inside a comprehension.
- You can flatten nested data using a nested comprehension.
- You know when a comprehension helps readability, and when a loop is clearer.
- You are ready to learn about regular expressions.