Skip to content

List and Dictionary Comprehensions ​

"For every student in the class, write down their name in capitals." One sentence, and everyone knows exactly what list you'll end up with.

In Lists, you built new lists with a pattern that you'll use constantly: start with an empty list, loop, and append.

python
scores = [88, 94, 72, 65, 91]
curved = []
for score in scores:
    curved.append(score + 5)
print(curved)
text
[93, 99, 77, 70, 96]

That's four lines for one idea: "each score, plus 5." Python has a shorter way to say exactly that, called a comprehension:

python
scores = [88, 94, 72, 65, 91]
curved = [score + 5 for score in scores]
print(curved)
text
[93, 99, 77, 70, 96]

Same result, one line, and once you're used to it, it reads almost like the sentence you'd say out loud.

Saying what you want, not how to build it ​

Imagine asking a classmate for help. You could say: "Take a blank sheet. Look at the first name on the list. Write it in capitals. Look at the next name. Write it in capitals. Keep going until you run out." Or you could just say: "Write down every name on the list, in capitals."

The loop version is the first set of instructions: it describes each step of building the list. A comprehension is the second: it describes the list you want, and Python works out the steps.

Reading a list comprehension ​

A list comprehension has three parts, inside square brackets:

text
[ expression   for item in collection ]
  what to keep   where it comes from

Read it as: "the expression, for each item in the collection." Some examples:

python
names = ["maria", "ben", "carlo"]
print([name.title() for name in names])
print([len(name) for name in names])
print([n * n for n in range(1, 6)])
text
['Maria', 'Ben', 'Carlo']
[5, 3, 5]
[1, 4, 9, 16, 25]

A good way to read one you haven't seen before: start in the middle, at the for, to see what's being looped over. Then read the beginning, to see what happens to each item.

Filtering with if ​

Add an if at the end, and only the items that pass the test are kept:

python
scores = [88, 94, 72, 65, 91]
passing = [score for score in scores if score >= 75]
print(passing)
text
[88, 94, 91]

That's the four-line "build a list of passing scores" loop from Lists, in one line. You can transform and filter at the same time, too:

python
words = ["apple", "Banana", "cherry", "Avocado"]
a_words = [word.lower() for word in words if word.lower().startswith("a")]
print(a_words)
text
['apple', 'avocado']

Choosing between two values ​

The if at the end filters: it decides which items to keep. To keep every item but change what's written depending on a condition, put a conditional expression, from Making Decisions, at the start:

python
scores = [88, 94, 72, 65, 91]
results = ["pass" if score >= 75 else "fail" for score in scores]
print(results)
text
['pass', 'pass', 'fail', 'fail', 'pass']

Notice the difference: filtering gave a shorter list, but this gives one result for every score.

Dictionary comprehensions ​

The same idea builds dictionaries. Use curly braces, and write a key: value pair at the start:

python
names = ["Maria", "Ben", "Carlo"]
name_lengths = {name: len(name) for name in names}
print(name_lengths)

prices = {"adobo": 65, "rice": 15, "juice": 20}
on_sale = {item: price * 0.9 for item, price in prices.items() if price > 18}
print(on_sale)
text
{'Maria': 5, 'Ben': 3, 'Carlo': 5}
{'adobo': 58.5, 'juice': 18.0}

The second one reads: "each item and its price times 0.9, for each item and price in the menu, if the price is over 18."

Set comprehensions ​

Curly braces with a single value, not a pair, make a set, from Sets, so duplicates disappear automatically:

python
words = ["cat", "dog", "car", "door", "cow"]
first_letters = {word[0] for word in words}
print(sorted(first_letters))
text
['c', 'd']

When not to use one ​

Comprehensions are great for simple transformations and filters. They're not a replacement for every loop. Use a regular for loop when:

  • you need to do something for each item, like printing or saving, rather than build a collection;
  • the logic needs several steps, or an elif;
  • the comprehension no longer fits comfortably on one line.

If you have to read a comprehension three times to understand it, write the loop. Clear beats clever, every time.

Try it ​

This program processes a class's quiz results with comprehensions: curving scores, filtering, labeling, and building a dictionary. Predict every line.

zip(names, scores) pairs up the two lists item by item: ("maria", 88), ("ben", 72), and so on. It's the tidy way to loop through two lists that line up.

Running Python here

Running Python right in the browser is coming to Syntaxia soon. For now, you can read and edit the code here. If you have Python installed on your computer (see Setting Up), save it as main.py and run it with python main.py (or python3 main.py on macOS and Linux).

Check your prediction
text
['Maria', 'Ben', 'Carlo', 'Dina', 'Eli']
[77, 72]
['B', 'C or below', 'A', 'C or below', 'B']
{'Maria': 88, 'Ben': 72, 'Carlo': 95, 'Dina': 67, 'Eli': 81}
Honor roll: ['Maria', 'Carlo']
Initials: MBCDE
Squares of odd numbers: [1, 9, 25, 49, 81]

The second line only curves the scores below 75, so it's shorter than the original list. The third line uses two conditional expressions in a row, which works but is right at the edge of readable. The initials line has no square brackets inside join: a comprehension written straight inside a function call works too, and makes the items one at a time.

Try it yourself ​

  1. Write a comprehension that gives the names with more than 3 letters.
  2. Rewrite the grade-labeling line (the third print) as a regular for loop with if, elif, and else. Which version do you find easier to read?
  3. Build a dictionary that maps each number from 1 to 5 to its cube, like {1: 1, 2: 8, ...}.

Check your understanding ​

What does [n * 2 for n in range(4)] give?
What does the if in [s for s in scores if s >= 75] do?
When is a regular for loop better than a comprehension?

Up next ​

Real data rarely fits in one flat list. A class has students, each student has several scores, and each score belongs to a subject. Next, you'll put lists inside dictionaries, and dictionaries inside lists, in Nested Data Structures.

← Sets
Nested Data Structures →

Answer the quiz above correctly to continue.