Learn

Short lessons with real code you can edit and run on the page.

List Comprehension in Python

Lesson 18 Python 3.14 Runs in your browser Updated
In short

A list comprehension builds a new list from an iterable in one expression inside square brackets. [n * n for n in range(5)] does the job of a for loop that appends n * n to an empty list, and an if at the end filters the items. Comprehensions are the usual way to build a list from another one in Python.

Key facts

  • [n * n for n in range(5)] builds [0, 1, 4, 9, 16] in one expression, the same list a for loop with append() would build.
  • The parts are an expression, a for clause and an optional if filter, in that order.
  • An if after the for keeps or drops items. An if ... else before the for changes them.
  • Two for clauses run like nested loops, with the first one outer.
  • A comprehension always builds a new list and leaves the source unchanged.

What is list comprehension in Python?

A list comprehension builds a new list from an iterable in one expression inside square brackets. It does the job of a for loop that starts with an empty list and appends one value per pass, and it reads as a description of the list rather than as instructions for building it.

Python
squares = []
for n in range(1, 6):
    squares.append(n * n)
print(squares)
squares = [n * n for n in range(1, 6)]
print(squares)
Output
[1, 4, 9, 16, 25]
[1, 4, 9, 16, 25]

Both versions print the same list. The loop version needs three lines, a variable to hold the result and an append() call on every pass. The comprehension names the value to keep, n * n, then the loop that supplies n, and Python builds the list in one go.

What is the syntax of a list comprehension?

The form is [expression for item in iterable], with an optional if condition at the end. The expression says what goes into the new list, the for clause names each item and where the items come from, and the condition, when present, decides which items are kept.

Parts of a Python list comprehension
PartExampleWhat it does
Expressionprice * 2The value stored for each item, which can be the item itself
for clausefor price in pricesThe loop variable and the iterable, written like a for loop header without the colon
if clauseif price > 5Optional, keeps only the items for which the condition is true
Python
prices = [4, 10, 25]
doubled = [price * 2 for price in prices]
print(doubled)
print(prices)
names = ["ada", "bob"]
print([name.upper() for name in names])
print([len(name) for name in names])
Output
[8, 20, 50]
[4, 10, 25]
['ADA', 'BOB']
[3, 3]

The expression can call methods and functions on the item, as name.upper() and len(name) do, and the source list is never changed. The iterable can be anything a for loop accepts, including a string or a range().

How do I add a condition to a list comprehension?

Write if and the condition after the for clause. Items that fail the test are skipped, so the condition works as a filter and the new list can be shorter than the source.

Python
nums = [3, 8, 5, 12, 7]
evens = []
for n in nums:
    if n % 2 == 0:
        evens.append(n)
print(evens)
print([n for n in nums if n % 2 == 0])
print([n for n in nums if n > 5])
Output
[8, 12]
[8, 12]
[8, 12, 7]

The if at the end takes no else, because it only decides whether an item is kept. Two conditions can be joined with and or or, the same logical operators an if statement uses.

How do I use if and else in a list comprehension?

Put the if and else before the for, as part of the expression. "even" if n % 2 == 0 else "odd" is a conditional expression that picks one of two values, so every item still produces something and the new list has the same length as the source.

Python
nums = [3, 8, 5, 12]
labels = ["even" if n % 2 == 0 else "odd" for n in nums]
print(labels)
capped = [n if n < 10 else 10 for n in nums]
print(capped)
print([n * 2 if n > 5 else n for n in nums if n != 3])
Output
['odd', 'even', 'odd', 'even']
[3, 8, 5, 10]
[16, 5, 24]

The position is the whole rule. An if before the for changes items and needs an else, and an if after the for drops items and can't have one. The last line uses both, and the filter runs first, so 3 never reaches the expression.

Can a list comprehension have two for loops?

Yes. Write the for clauses one after another in the same order as the nested loops they replace, with the outer loop first. Each item of the first loop is paired with every item of the second.

Python
colors = ["red", "blue"]
sizes = ["S", "M"]
pairs = []
for color in colors:
    for size in sizes:
        pairs.append(color + " " + size)
print(pairs)
print([color + " " + size for color in colors for size in sizes])
grid = [[1, 2], [3, 4], [5, 6]]
print([n for row in grid for n in row])
Output
['red S', 'red M', 'blue S', 'blue M']
['red S', 'red M', 'blue S', 'blue M']
[1, 2, 3, 4, 5, 6]

The last comprehension flattens a list of lists, and it reads the same way as the loop it replaces, row by row and then item by item. Two for clauses are the sensible limit, because a third makes the line hard to read, and a plain nested loop is the better choice at that point.

Should I use a list comprehension or a for loop?

Use a comprehension when the only job of the loop is building a list. Use a for loop when it does anything else.

A comprehension is the wrong tool for printing. The list it builds would hold nothing but None, because print() returns None, and the printing was the only thing you wanted. A comprehension also can't stop early with break or hold several statements, so a loop body with more than one step belongs in a loop.

Python list comprehension compared with a for loop
FormWhat it doesUse it when
List comprehensionBuilds a new list from one expression, in one lineThe result is a list and the expression fits on one line
for loopRuns any statements once per itemThe body prints, updates other variables, needs break or continue, or has several steps

Speed is not the reason to choose. A comprehension is often a little faster than the equivalent loop, because Python skips the repeated append() call, but the difference is small for everyday lists and readability decides.

Common mistakes with list comprehensions in Python

These four mistakes with list comprehensions are the common ones. Two are syntax errors that Python reports at once, and two produce code that runs but is wrong or hard to read.

  • SyntaxError: expected 'else' after 'if' expression. An if was placed before the for without an else. Move it after the for to filter, or add the else to choose a value.
  • SyntaxError: invalid syntax. An else followed the filter at the end. The filter takes no else, so move the whole if ... else before the for.
  • Forgetting the square brackets. squares = (n * n for n in nums) with parentheses creates a generator, not a list. A generator is a different kind of value, and for now the thing to know is that printing one shows <generator object ...> instead of the numbers. Use square brackets for a list.
  • Cramming too much in. A comprehension with two conditions, an if/else and two for clauses is valid Python and unreadable. Split it into a loop.

Run the two broken programs to see the messages, then fix them in the editor.

Python
nums = [3, -1, 4]
print([n if n > 0 for n in nums])
Output
  File "main.py", line 2
    print([n if n > 0 for n in nums])
           ^^^^^^^^^^
SyntaxError: expected 'else' after 'if' expression
Python
nums = [3, -1, 4]
print([n for n in nums if n > 0 else 0])
Output
  File "main.py", line 2
    print([n for n in nums if n > 0 else 0])
                                    ^^^^
SyntaxError: invalid syntax

Exercise

Complete the comprehension so it keeps only the words longer than four letters and converts each one to uppercase with upper(), printing ['APPLE', 'BANANA']. The starter copies every word unchanged.

Python
words = ["apple", "kiwi", "banana", "fig"]
long_words = [word for word in words]
print(long_words)
Output
Show the solution
words = ["apple", "kiwi", "banana", "fig"]
long_words = [word.upper() for word in words if len(word) > 4]
print(long_words)

Quiz

This quiz has 5 questions. Pick an answer to see why it is right or wrong.

  1. 1What does this program print?

    print([x * 2 for x in [1, 2, 3]])
  2. 2What does this program print?

    print([x for x in range(6) if x % 2 == 0])
  3. 3Which comprehension is written correctly?

  4. 4What does this program print?

    print(len([a + b for a in "xy" for b in "12"]))
  5. 5What does the if at the end of [n for n in nums if n > 0] do?

Frequently asked questions

What is list comprehension in Python?
A list comprehension is an expression in square brackets that builds a new list from an iterable. [n * n for n in range(5)] does the same job in one line as a for loop that appends n * n to an empty list.
When should I use a list comprehension instead of a for loop?
Use a comprehension when the loop's only job is to build a list. Use a for loop when the body has several steps, prints something, or needs to stop early with break.
Is a list comprehension faster than a for loop?
Usually a little, because Python skips the repeated append() call, but the gap is small for everyday lists. Choose a comprehension for readability, not speed, and measure with Python's timeit module, a built-in stopwatch for small pieces of code, when speed matters.
Can I use if and else in a list comprehension?
Yes, as a conditional expression before the for. [x if x > 0 else 0 for x in nums] replaces negatives with 0, while an if after the for is a filter and cannot take an else.
Can a list comprehension have two for loops?
Yes. Write the for clauses in the same order as the nested loops they replace, so [a + b for a in xs for b in ys] pairs every a with every b, and keep it to two levels for readability.
Why is it called a list comprehension?
The name comes from set-builder notation in mathematics. That notation describes a set by a rule for its members and is called a comprehension, and a list comprehension describes a list the same way.
Is a list comprehension a different kind of list?
No. A list comprehension is one way of writing the code that builds an ordinary list, and its result is a normal list you can index, slice and change.