W3docs

List Comprehension

Learn Python list comprehension syntax, filtering, nested loops, dict and set comprehensions, and when to use them with runnable examples.

Python List Comprehension

List comprehension is a concise way to build a new list by applying an expression to every item in an iterable — optionally filtering items with a condition — all in a single readable line. This page covers the full syntax, common patterns, dict and set comprehensions, and guidance on when a plain for loop is the better choice.

Syntax

The general form of a list comprehension is:

new_list = [expression for item in iterable if condition]
PartRole
expressionValue placed in the new list for each item
itemLoop variable, takes each value from iterable in turn
iterableAny sequence or iterable: list, tuple, string, range, etc.
if conditionOptional filter — only items where the condition is True are included

The if condition part is optional. When omitted, every item in the iterable produces one entry in the new list.

Basic Example: Squaring Numbers

The equivalent for loop requires three lines; list comprehension does the same in one:

python— editable, runs on the server

Filtering with a Condition

Add an if clause after the iterable to keep only the items that satisfy a condition:

python— editable, runs on the server

You can combine any predicate. For example, keeping words that are longer than four characters:

words = ['hi', 'hello', 'world', 'python', 'ai']
long_words = [w for w in words if len(w) > 4]
print(long_words)  # ['hello', 'world', 'python']

if/else in the Expression (Ternary)

When you need to transform every item but apply different logic depending on a condition, put the if/else inside the expression part (before for), not after the iterable:

numbers = range(1, 6)
labels = ['even' if x % 2 == 0 else 'odd' for x in numbers]
print(labels)  # ['odd', 'even', 'odd', 'even', 'odd']

Note the difference:

  • [expr for x in it if cond] — filter: skips items where cond is False
  • [a if cond else b for x in it] — transform: every item produces a value, chosen by cond

Working with Strings

List comprehension works on any iterable, including strings and lists of strings:

words = ['hello', 'world', 'python']
upper_words = [w.upper() for w in words]
print(upper_words)  # ['HELLO', 'WORLD', 'PYTHON']

Extract individual characters that meet a condition:

vowels = [ch for ch in 'programming' if ch in 'aeiou']
print(vowels)  # ['o', 'a', 'i']

Nested Loops

List comprehension supports multiple for clauses, equivalent to nested loops. The leftmost for is the outer loop:

python— editable, runs on the server

A common use case for nested list comprehension is flattening a 2-D list (matrix) into a 1-D list:

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [n for row in matrix for n in row]
print(flat)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

Reading tip: mentally expand nested comprehensions as nested for loops in the same left-to-right order.

Dictionary Comprehension

The same idea applies to dictionaries using {} with a key: value expression:

keys = ['a', 'b', 'c']
values = [1, 2, 3]
mapping = {k: v for k, v in zip(keys, values)}
print(mapping)  # {'a': 1, 'b': 2, 'c': 3}

Swap keys and values in an existing dictionary:

original = {'name': 'Alice', 'city': 'Paris'}
inverted = {v: k for k, v in original.items()}
print(inverted)  # {'Alice': 'name', 'Paris': 'city'}

Set Comprehension

Use {} with a single expression (no colon) to build a set, which automatically removes duplicates:

numbers = [1, 2, 2, 3, 3, 3, 4]
unique_squares = {x ** 2 for x in numbers}
print(unique_squares)  # {1, 4, 9, 16}

The result is unordered (sets have no guaranteed order), so do not rely on the printed sequence.

Performance

List comprehensions are generally faster than equivalent for loops that call .append() because the interpreter can optimize the internal loop in C. For timing your own code, use the timeit module:

import timeit

loop_time = timeit.timeit(
    'result = []\nfor x in range(1000):\n    result.append(x**2)',
    number=10000
)
comp_time = timeit.timeit(
    '[x**2 for x in range(1000)]',
    number=10000
)
print(f'Loop: {loop_time:.3f}s')
print(f'Comprehension: {comp_time:.3f}s')
# Comprehension is typically 20-40% faster

Performance advantage shrinks or disappears when the expression itself is slow (network I/O, heavy computation). Profile before optimizing.

When to Use a Plain for Loop Instead

List comprehension is not always the right tool:

SituationPrefer
Single transformation or filterList comprehension
Multiple side effects per iteration (logging, mutating state)for loop
Complex logic that needs several statementsfor loop
Deeply nested comprehensions (more than two levels)for loop — readability wins
The result is never stored (you only need to iterate)Generator expression ((x for x in ...))

The clearest signal to switch back to a for loop is when you find yourself squinting at the comprehension to understand what it does.

Gotchas

Variable leakage does not happen in Python 3. The loop variable in a comprehension is scoped to the comprehension itself:

x = 'original'
result = [x * 2 for x in range(3)]
print(x)  # 'original' — not overwritten by the comprehension's x

Avoid deeply nested comprehensions. More than two for clauses in a single comprehension hurts readability with little benefit. Break them up into named intermediate lists or for loops.

Generator expressions save memory. If you only need to iterate over the result once (e.g., pass it to sum() or max()), replace [] with () to get a generator that yields items one at a time:

total = sum(x ** 2 for x in range(1, 1001))
print(total)  # 333833500

Practice

Practice
What is true about list comprehension in Python according to the information given in the URL?
What is true about list comprehension in Python according to the information given in the URL?
Was this page helpful?