🎓 A1Learner
🔍
0 of 102 lessons completed

Python Comprehensions in Depth

A nested comprehension is a comprehension with more than one for.

Flatten a matrix

Read the for parts left to right. The first for picks a row.

matrix = [[1, 2], [3, 4]]
flat = [value for row in matrix for value in row]
print(flat)

Add a filter

Put if at the end. It tests each value from the inner for.

matrix = [[1, 2], [3, 4]]
evens = [value for row in matrix for value in row if value % 2 == 0]
print(evens)

Set comprehension edge case

A set keeps each result once. Two words here share the same length.

words = ["cat", "dog", "bird", "ant"]
lengths = {len(word) for word in words}
print(sorted(lengths))

Dict comprehension edge case

A dict keeps one value per key. The last pair for a key wins.

pairs = [("a", 1), ("b", 2), ("a", 3)]
scores = {name: score for name, score in pairs}
print(scores)

Store it once with the walrus

The walrus operator is :=. It stores the number and tests that same number.

texts = ["10", "3", "25"]
big = [number for text in texts if (number := int(text)) >= 10]
print(big)

When a loop reads better

This loop does the same flatten job. Each step sits on its own line.

matrix = [[1, 2], [3, 4]]
flat = []
for row in matrix:
    for value in row:
        flat.append(value)
print(flat)

Example

grades = [["85", "42", "90"], ["55", "78", "30"]]

passing_loop = []
for row in grades:
    for text in row:
        mark = int(text)
        if mark >= 50:
            passing_loop.append(mark)

passing_comp = [int(text) for row in grades for text in row if int(text) >= 50]

passing_walrus = [mark for row in grades for text in row if (mark := int(text)) >= 50]

print(passing_loop)
print(passing_comp)
print(passing_walrus)

Key points

  • Nested comprehension: a comprehension with more than one for
  • Read nested comprehensions left to right, in loop order
  • Place if at the end to filter the values the for parts make
  • Set comprehension: {expr for ...} drops duplicate results
  • Dict comprehension: a repeated key keeps its last value
  • Walrus operator: := stores a value and gives it back at once
  • Use a plain loop when a comprehension needs many lines to read

In this example, grades holds marks as text. The loop version converts each mark once. It keeps marks of 50 or more. The nested comprehension does the same job in one line. It reads row by row and then mark by mark. For a passing mark, it works the conversion out twice. The walrus version stores int(text) as mark. It tests mark and then keeps that same mark. All three lists print the same passing marks.

Note

In Python, := inside a condition lets you test the stored value.

The stored value needs no second calculation.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Python Playground

Exercise

How do you read [v for row in grid for v in row]?