Unit 17: Comprehensions
Building lists in one line.
Unit 17 of 31 in Python for kids. Its 5 lessons are Lists in One Line, Choosing As You Build, Counting Things, Dictionaries With a Backup Plan and Comprehension Master — below is everything each one explains, and a question or two from it to try.
Every sample on this page was run through real Python before it shipped, and prints exactly what it says it prints.
This unit opens with a fortnight’s trial of everything — no card needed — or with a family plan, bought in the iPhone app. The first two units of every track are free for ever. Try it in the app.
✨ Lists in One Line
The loop that fits in the brackets
Building a list with a loop takes four lines. A list comprehension says the same thing in one: what to keep, then where it comes from.
Python
nums = [1, 2, 3]
doubled = []
for n in nums:
doubled.append(n * 2)
print(doubled)
print([n * 2 for n in nums])
It prints
[2, 4, 6] [2, 4, 6]
It works on anything you can loop over
Text, ranges, lists — anything a for can walk through.
Python
print([c.upper() for c in "abc"])
print([n * n for n in range(1, 5)])
It prints
['A', 'B', 'C'] [1, 4, 9, 16]
Try it yourself
In [n * 2 for n in nums], which part says what goes in the list?
- for n
- in nums
- n * 2
- the brackets
What does this print?
Python
print([n + 1 for n in [10, 20, 30]])
Answer them in the app
🧲 Choosing As You Build
Adding an if on the end
An if at the end keeps only the items you want — the same job filter does, in fewer moving parts.
Python
nums = [1, 2, 3, 4, 5, 6]
print([n for n in nums if n % 2 == 0])
It prints
[2, 4, 6]
Choosing and changing at once
You can filter and transform in the same line: keep the even ones, and double them on the way past.
Python
nums = [1, 2, 3, 4]
print([n * 10 for n in nums if n % 2 == 0])
It prints
[20, 40]
Dictionaries too
Swap the square brackets for curly ones and give a key and a value, and you build a dictionary the same way.
Python
print({n: n * n for n in [1, 2, 3]})
It prints
{1: 1, 2: 4, 3: 9}
Try it yourself
What does this print?
Python
words = ["fig", "pear", "kiwi"]
print([w for w in words if len(w) > 3])
Which is the tidier way to keep only the big numbers?
- [n for n in nums if n > 10]
- list(filter(lambda n: n > 10, nums))
- Both work; the first is what most Python programmers write
- Neither works
Answer them in the app
🧮 Counting Things
The counting done for you
Counting how often each thing appears is so common that Python ships a tool for it. Counter takes anything you can loop over and tallies it up.
Python
from collections import Counter
votes = ["red", "blue", "red"]
counts = Counter(votes)
print(counts["red"])
print(counts["green"])
It prints
2 0
A missing thing counts as zero
Ask an ordinary dictionary for a key it has never seen and it stops with an error. A Counter calmly answers 0, which is almost always what you meant.
Python
from collections import Counter
c = Counter("banana")
print(c["a"])
print(c["z"])
It prints
3 0
The most popular ones
most_common(n) gives the top few, biggest first, as pairs.
Python
from collections import Counter
c = Counter(["a", "b", "a", "c", "a", "b"])
print(c.most_common(2))
It prints
[('a', 3), ('b', 2)]
Try it yourself
What does this print?
Python
from collections import Counter
print(Counter("hello")["l"])
Answer it in the app
🪺 Dictionaries With a Backup Plan
The missing-key problem
Adding to a list inside a dictionary is awkward, because the first time round there is no list there yet.
Python
groups = {}
for word in ["ant", "bee", "ape"]:
letter = word[0]
if letter not in groups:
groups[letter] = []
groups[letter].append(word)
print(groups)
It prints
{'a': ['ant', 'ape'], 'b': ['bee']}
defaultdict makes it for you
A defaultdict builds a starting value the first time you touch a key. Give it list and every new key begins as an empty list.
Python
from collections import defaultdict
groups = defaultdict(list)
for word in ["ant", "bee", "ape"]:
groups[word[0]].append(word)
print(dict(groups))
It prints
{'a': ['ant', 'ape'], 'b': ['bee']}
Give it int to count
With int, every new key starts at 0 — so you can add to it straight away.
Python
from collections import defaultdict
tally = defaultdict(int)
for letter in "hello":
tally[letter] += 1
print(dict(tally))
It prints
{'h': 1, 'e': 1, 'l': 2, 'o': 1}
Try it yourself
What does defaultdict(list) do the first time you use a new key?
- Crashes
- Puts an empty list there for you
- Returns None
- Puts a 0 there
Answer it in the app
🏆 Comprehension Master
Try it yourself
What does this print?
Python
print([n for n in range(10) if n % 3 == 0])
Answer it in the app