- Replace a loop with a list comprehension
- Add a filter condition and an
if ... elseexpression to a comprehension - Write dictionary and set comprehensions
In the lesson on lists we built new lists like this: create an empty list, write a loop, append on every step. That takes three or four lines. Python has a special syntax that does the same in one line — the comprehension. Professional Python programmers use it every day.
List comprehension
Inside square brackets you first write the expression to calculate for each item, followed by an ordinary for part. Both ways give the same result — compare them:
squares = []
for n in range(1, 6):
squares.append(n * n)
print(squares)
squares = [n * n for n in range(1, 6)]
print(squares)▸ Expected output
[1, 4, 9, 16, 25] [1, 4, 9, 16, 25]
[expression for item in iterable if condition]
{key: value for item in iterable if condition}
{expression for item in iterable}if part is optional.The real power of a comprehension is the filter: an if at the end keeps only the items that match the condition. The expression can be anything — a method call, a function, a calculation:
numbers = [12, 7, 30, 5, 18, 21]
evens = [n for n in numbers if n % 2 == 0]
print(evens)
names = ['aysel', 'tural', 'ali']
print([name.title() for name in names])
print([len(name) for name in names])▸ Expected output
[12, 30, 18] ['Aysel', 'Tural', 'Ali'] [5, 5, 3]
If you don't want to drop items but to transform them in two different ways, use a conditional expression: A if condition else B. Note that this goes before the for, while a filter if goes after it.
numbers = [3, 8, 11, 14]
labels = ['even' if n % 2 == 0 else 'odd' for n in numbers]
print(labels)▸ Expected output
['odd', 'even', 'odd', 'even']
Dictionary comprehension
Write curly braces and a key: value pair, and you get a dictionary instead of a list. This is very handy for building a dictionary from a list, changing values or filtering pairs. The shop has started a 10% sale:
names = ['Aysel', 'Tural', 'Ali']
lengths = {name: len(name) for name in names}
print(lengths)
prices = {'bread': 0.8, 'milk': 1.9, 'cheese': 6.5}
sale = {item: round(price * 0.9, 2) for item, price in prices.items()}
print(sale)
scores = {'Aysel': 91, 'Murad': 48, 'Leyla': 76}
passed = {name: s for name, s in scores.items() if s >= 50}
print(passed)▸ Expected output
{'Aysel': 5, 'Tural': 5, 'Ali': 3}
{'bread': 0.72, 'milk': 1.71, 'cheese': 5.85}
{'Aysel': 91, 'Leyla': 76}Set comprehensions and generator expressions
Write a single expression in curly braces and you get a set — duplicates are removed automatically. If you drop the brackets and pass the comprehension straight to a function, you get a generator expression: it produces the items one by one without building a separate list, which saves memory.
words = ['sun', 'moon', 'star', 'sky', 'planet']
lengths = {len(w) for w in words}
print(sorted(lengths))
total = sum(n * n for n in range(1, 11))
print(total)
table = [[1, 2, 3], [4, 5, 6]]
flat = [n for row in table for n in row]
print(flat)▸ Expected output
[3, 4, 6] 385 [1, 2, 3, 4, 5, 6]
for parts: the outer one goes through the rows, the inner one through the numbers in each row.Generator expressions are especially useful with the any() and all() functions. any() returns True when at least one item matches the condition, and all() when every item does. This lets you answer questions like “Did anyone fail the test?” or “Did everyone score above 40?” in one line.
scores = [72, 45, 88, 91]
print(any(s < 50 for s in scores))
print(all(s > 40 for s in scores))
print(max(len(w) for w in ['sun', 'planet', 'sky']))▸ Expected output
True True 6
Daytime temperatures in Baku over a week: 24, 27, 31, 29, 33, 26, 30 °C. Find how many days were 30 °C or hotter and give those temperatures in Fahrenheit.
Show solutionHide solution
hot = [t for t in temps if t >= 30].len(hot) gives the count.Convert each one with
t * 9 / 5 + 32: [t * 9 / 5 + 32 for t in hot].The result is in the code below: 3 days.
temps = [24, 27, 31, 29, 33, 26, 30]
hot = [t for t in temps if t >= 30]
print('Hot days:', len(hot))
print([t * 9 / 5 + 32 for t in hot])▸ Expected output
Hot days: 3 [87.8, 91.4, 86.0]
Use list comprehensions to build and print two new lists: 1) the squares of the odd numbers in numbers, 2) the words from words that are longer than 3 letters, in capitals. Each one should be a one-line comprehension.
numbers = [4, 7, 10, 3, 8, 5]
words = ['sun', 'Baku', 'python', 'sea', 'tea', 'Caspian']
# 1) odd_squares: squares of the odd numbers
# 2) long_words: words longer than 3 letters, in capitals
# print both lists▸ Expected output
[49, 9, 25] ['BAKU', 'PYTHON', 'CASPIAN']
Use a dictionary comprehension to build results: the key is the pupil's name and the value is 'pass' if the score is at least 50, otherwise 'fail'. Print it. Then print the sum of the passing scores using a generator expression and sum().
scores = {'Aysel': 91, 'Murad': 48, 'Leyla': 76, 'Elvin': 55}
# 1) results: name -> 'pass' or 'fail'
# 2) print results
# 3) print the sum of the scores that are at least 50▸ Expected output
{'Aysel': 'pass', 'Murad': 'fail', 'Leyla': 'pass', 'Elvin': 'pass'}
222Key points
[expression for x in sequence]builds a new list in one line.- An
ifat the end filters items;A if condition else Bbefore thefortransforms them in two ways. {k: v for ...}creates a dictionary, and{x for ...}creates a set.- A generator expression such as
sum(x * x for x in ...)does not build a separate list. - If a comprehension gets complicated, go back to a normal loop.
Check yourself
10 questions. Every correct answer earns XP.
[n * 2 for n in range(3)]?