1. Introduction
List comprehension is a concise, expressive Python syntax for creating a new list by applying an expression to each item of an iterable, optionally filtering items with a condition. It replaces the more verbose pattern of building a list with a for loop and repeated .append() calls.
Cricket analogy: '[run*4 if boundary else run for run in deliveries]' replaces a scorer manually looping ball by ball and appending totals to a tally sheet -- one concise line building the whole innings list.
Beyond brevity, list comprehensions are often more readable and can be slightly faster than equivalent explicit loops, because the looping and appending happen at the C level inside the Python interpreter.
Cricket analogy: A comprehension building an over's boundary count runs the looping internally at C speed, like a stadium's electronic scoreboard updating instantly rather than a scorer manually chalking each run by hand.
2. Syntax
# Basic syntax: [expression for item in iterable]
squares = [x ** 2 for x in range(6)]
# With a condition (filter)
evens = [x for x in range(10) if x % 2 == 0]
# With an if-else expression
labels = ["even" if x % 2 == 0 else "odd" for x in range(5)]
# Nested comprehension (flattening a 2D list)
matrix = [[1, 2], [3, 4], [5, 6]]
flat = [num for row in matrix for num in row]
# Equivalent generator expression (uses parentheses)
squares_gen = (x ** 2 for x in range(6))3. Explanation
A list comprehension has the general form [expression for item in iterable if condition], where the if condition clause is optional and filters which items are included. Multiple for clauses can be chained to flatten nested structures or produce combinations.
Cricket analogy: '[player for team in tournament for player in team.squad]' flattens every squad across a tournament into one list, like a stats site compiling every player across all IPL franchises into a single leaderboard.
A closely related construct is the generator expression, which uses parentheses () instead of square brackets []. While it looks almost identical, it produces items lazily one at a time instead of building the entire list in memory upfront.
Cricket analogy: '(run for run in deliveries)' is like a radio commentator calling out each run live as it happens rather than a printed scorecard prepared all at once -- lazy, one delivery at a time.
List comprehension vs generator expression memory difference: [x**2 for x in range(10**8)] builds the ENTIRE list in memory immediately (can be gigabytes), while (x**2 for x in range(10**8)) creates a generator that computes each value lazily on demand, using constant memory regardless of size.
Overusing deeply nested list comprehensions (multiple for and if clauses in one line) hurts readability. If a comprehension needs more than two levels of nesting or complex logic, a regular for loop is usually clearer and easier to debug.
4. Example
numbers = range(10)
squares = [x ** 2 for x in numbers]
print("squares:", squares)
evens_squared = [x ** 2 for x in numbers if x % 2 == 0]
print("evens squared:", evens_squared)
labels = ["even" if x % 2 == 0 else "odd" for x in range(5)]
print("labels:", labels)
matrix = [[1, 2], [3, 4], [5, 6]]
flat = [num for row in matrix for num in row]
print("flat:", flat)
gen = (x ** 2 for x in range(5))
print("generator type:", type(gen))
print("generator values:", list(gen))5. Output
squares: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
evens squared: [0, 4, 16, 36, 64]
labels: ['even', 'odd', 'even', 'odd', 'even']
flat: [1, 2, 3, 4, 5, 6]
generator type: <class 'generator'>
generator values: [0, 1, 4, 9, 16]6. Key Takeaways
- List comprehension syntax:
[expression for item in iterable if condition]. - The
ifclause filters items; anif-elsebefore theforacts as a conditional expression per item. - Multiple
forclauses can flatten nested lists in a single comprehension. - List comprehensions build the full list in memory immediately; generator expressions
()compute values lazily, saving memory for large sequences. - List comprehensions are often faster and more readable than an equivalent
forloop with.append(). - Avoid overly complex, deeply nested comprehensions — prefer a regular loop when readability suffers.
Practice what you learned
1. What is the correct syntax for a basic list comprehension that squares each number in `range(5)`?
2. What is the key memory difference between `[x for x in range(10**8)]` and `(x for x in range(10**8))`?
3. What does `[x for x in range(10) if x % 2 == 0]` produce?
4. How do you flatten `[[1,2],[3,4]]` into `[1,2,3,4]` using a list comprehension?
5. What type does `(x ** 2 for x in range(5))` evaluate to?
6. Which placement is correct for an if-else conditional expression inside a list comprehension?
Was this page helpful?
You May Also Like
Lists in Python
A mutable, ordered sequence type in Python used to store collections of items, with a deep dive into mutation, aliasing, and common list operations.
Sets in Python
An unordered collection of unique, hashable elements in Python, covering set creation, operations, and the no-order/no-duplicates gotcha.
Dictionaries in Python
Python's key-value mapping type, covering hashable keys, insertion order guarantees (3.7+), common dict methods, and typical gotchas.
Generators in Python
Learn how to write generator functions with yield to produce lazy, memory-efficient sequences of values in Python.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics