What Are List Comprehensions?

List comprehensions are a concise, Pythonic way to create lists from existing iterables. They compress what would normally be a multi-line for loop into a single, readable expression. Once you understand them, you'll find yourself reaching for them constantly.

The Basic Syntax

The general structure of a list comprehension is:

[expression for item in iterable if condition]

The if condition part is optional — it acts as a filter.

From Loop to Comprehension: A Side-by-Side Example

Let's say you want a list of squares for numbers 0 through 9.

Traditional loop:

squares = []
for n in range(10):
    squares.append(n ** 2)

List comprehension:

squares = [n ** 2 for n in range(10)]

Both produce [0, 1, 4, 9, 16, 25, 36, 49, 64, 81], but the comprehension is cleaner and more expressive.

Adding a Filter Condition

Only want the squares of even numbers?

even_squares = [n ** 2 for n in range(10) if n % 2 == 0]
# [0, 4, 16, 36, 64]

The if clause filters items before the expression is applied. This keeps the logic tight and readable.

Working with Strings

Comprehensions shine when transforming lists of strings:

names = ["alice", "bob", "charlie", "dave"]
capitalized = [name.capitalize() for name in names]
# ["Alice", "Bob", "Charlie", "Dave"]

long_names = [name for name in names if len(name) > 4]
# ["alice", "charlie"]

Nested List Comprehensions

You can nest comprehensions to flatten 2D lists or build matrices:

# Flatten a matrix
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

Be cautious with deeply nested comprehensions — readability can suffer quickly. If your comprehension spans more than two levels of nesting, a regular loop is often clearer.

Dictionary and Set Comprehensions

The same pattern works for dictionaries and sets:

# Dictionary comprehension
word_lengths = {word: len(word) for word in ["hello", "world", "python"]}
# {"hello": 5, "world": 5, "python": 6}

# Set comprehension (removes duplicates automatically)
unique_lengths = {len(word) for word in ["hi", "hello", "hey", "world"]}
# {2, 5}

When NOT to Use List Comprehensions

List comprehensions are powerful, but they're not always the right tool:

  • Complex logic: If your expression or condition requires multiple lines of logic, extract it into a function and call it in the comprehension — or just use a loop.
  • Side effects: Don't use comprehensions just to run side effects (like printing). That's what for loops are for.
  • Large datasets: If you're working with huge amounts of data, consider a generator expression instead — it uses () instead of [] and doesn't load the whole list into memory at once.
# Generator expression — memory efficient
total = sum(n ** 2 for n in range(1_000_000))

Quick Reference

TypeSyntaxResult
List[expr for x in iter]List
Dict{k: v for x in iter}Dictionary
Set{expr for x in iter}Set
Generator(expr for x in iter)Generator object

Summary

List comprehensions are one of the features that make Python feel elegant. They encourage you to think in transformations rather than mutations, which leads to cleaner, more functional-style code. Master them, use them where they improve readability, and reach for a regular loop when the logic gets complex. That balance is the mark of a confident Python developer.