Courses/Python Mastery/Module 10: Power Tools
Module 10 · Lesson 125 minBeginner

List & Dict Comprehensions

Lesson goal
Transform collections in one readable line — the #1 Pythonic skill.

List & Dict Comprehensions

Remember building lists with loops — empty list, append inside, three lines? Comprehensions do it in one line, and they're the single most "Pythonic" skill in the language. Code that uses them *reads* like Python was meant to read.

The upgrade path

The loop you know:

code
squares = []
for n in range(1, 6):
    squares.append(n ** 2)

print(squares)     # [1, 4, 9, 16, 25]

The comprehension — same result, one line:

code
squares = [n ** 2 for n in range(1, 6)]
print(squares)     # [1, 4, 9, 16, 25]

Read the comprehension left to right as a sentence: *"give me n squared, for each n in range 1 to 6."* The expression comes first, the loop after — backwards from a for loop, but natural once you read it as the outcome you're collecting.

Adding a condition: the filter

code
numbers = [1, 2, 3, 4, 5, 6, 7, 8]

evens = [n for n in numbers if n % 2 == 0]
print(evens)     # [2, 4, 6, 8]

big_evens = [n for n in numbers if n % 2 == 0 and n > 4]
print(big_evens) # [6, 8]

An if at the end keeps only matching items. Full sentence: *"give me n, for each n in numbers, if n is even."*

Transform AND filter together

code
words = ["apple", "banana", "avocado", "cherry", "apricot"]

a_words = [w.upper() for w in words if w.startswith("a")]
print(a_words)     # ['APPLE', 'AVOCADO', 'APRICOT']

Expression (transform) + loop (source) + condition (filter) — the three-part anatomy of every comprehension.

Dictionary comprehensions

Same idea, building dicts — {key: value for ...}:

code
marks = {"Aarav": 92, "Diya": 95, "Kabir": 78}

# invert a dict
inverted = {v: k for k, v in marks.items()}
print(inverted)     # {92: 'Aarav', 95: 'Diya', 78: 'Kabir'}

# filter + transform
toppers = {name: mark for name, mark in marks.items() if mark > 80}
print(toppers)      # {'Aarav': 92, 'Diya': 95}

# word lengths
words = ["apple", "banana", "kiwi"]
lengths = {w: len(w) for w in words}
print(lengths)      # {'apple': 5, 'banana': 6, 'kiwi': 4}

That last one — building a dict from a list — is a comprehension you'll write weekly.

Real-world one-liners you'll actually use

code
# clean a messy list of strings
raw = ["  Aarav ", "DIYA", " kabir "]
names = [name.strip().title() for name in raw]
print(names)     # ['Aarav', 'Diya', 'Kabir']

# numbers from strings (the input-conversion pattern!)
raw_input = ["10", "20", "30"]
values = [int(x) for x in raw_input]

# flatten a list of lists
grid = [[1, 2], [3, 4], [5, 6]]
flat = [num for row in grid for num in row]
print(flat)      # [1, 2, 3, 4, 5, 6]

That last one has TWO for clauses — "for each row in grid, for each num in row." Nested loops in one line. Readable? Debatable. Useful? Extremely.

When NOT to comprehend

If the logic needs multiple steps, try/except, or more than one condition plus a transform — use a regular loop. A comprehension you can't read in one breath is worse than a loop:

code
# ❌ too clever — nobody wants to parse this
result = [process(x) for x in data if x.valid and x.size > 10 and not x.skip and check(x)]

# ✅ a loop is honest about complexity
result = []
for x in data:
    if x.valid and x.size > 10 and not x.skip and check(x):
        result.append(process(x))

Comprehensions are for *one clear transformation*, not for hiding complexity.

Common Errors & Fixes

  • `NameError` on the loop variable outside — the variable leaks after the comprehension in some Python versions; don't rely on it existing.
  • `SyntaxError` with if/else placement — filter-if goes at the END ([x for x in xs if cond]); transform-if-else goes at the FRONT ([x if cond else y for x in xs]). Different positions, different jobs!
  • Missing brackets — comprehensions live inside [] or {}; a bare comprehension is a syntax error.

  • ✅ Checkpoint

  • Comprehension for cubes of 1–5? *([n ** 3 for n in range(1, 6)])*
  • Keep only strings longer than 5 from words? *([w for w in words if len(w) > 5])*
  • Build {word: len(word)} from a list? *({w: len(w) for w in words})*
  • Where does the filter-if go vs the if-else transform? *(Filter: end. If-else: front.)*
  • Next: generators — producing values lazily and handling infinite sequences.