Capstone day. Given ["hi", "hello", "ok", "world"] and a minimum length of 4, you want ["HELLO", "WORLD"] — only words longer than 3 characters, uppercased. Filter and transform, all five days of comprehensions collapsed into one expression.
Two steps: the filter len(w) > min_len and the transform w.upper(). Both live in the same comprehension?
Both fit in the same shape you've been building all week:
# Skeleton: [transform for x in xs if filter]
result = [w.upper() for w in words if len(w) > min_len]Read it left to right: "uppercase each word, for each word in words, if its length is greater than min_len." The filter runs first — only passing words reach .upper().
def uppercase_long_words(words: list, min_len: int) -> list:
return [w.upper() for w in words if len(w) > min_len]Four moves fused into one expression: iterate, filter, transform, collect.
What if min_len is 0 — does every word pass and get uppercased?
Every non-empty string has length at least 1, so len(w) > 0 is true for all of them. Empty strings fail the filter (0 is not greater than 0), so they drop out. That's the subtle power of strict inequality — it handles the empty-string edge case for free.
And if min_len is really large — say 100 — the comprehension returns [] because nothing passes?
Right. Too-strict filter → empty result. No crash, no special case. That's the same graceful degradation you've seen all week: comprehensions handle empty collections and empty filter-passing sets uniformly.
This one function uses every comprehension technique from the week — list, filter, transform. If I understand this shape, I understand comprehensions.
That's the whole week in one line. The same mental shape — expression, for, if — scales to dict and set comprehensions, to nested loops, to generator expressions. Master this one pattern and the rest are shape variations.
TL;DR: [f(x) for x in xs if cond(x)] is the universal shape — filter, then transform, in one expression.
if cond gates which items reach f(x)f(x) runs only on passing items| Goal | Shape |
|---|---|
| Transform every item | [f(x) for x in xs] |
| Filter and transform | [f(x) for x in xs if c] |
| Build a dict | {k: v for k, v in ps} |
| Dedupe unique values | {x for x in xs} |
Same mental model across all four — only the brackets and output shape change.
Capstone day. Given ["hi", "hello", "ok", "world"] and a minimum length of 4, you want ["HELLO", "WORLD"] — only words longer than 3 characters, uppercased. Filter and transform, all five days of comprehensions collapsed into one expression.
Two steps: the filter len(w) > min_len and the transform w.upper(). Both live in the same comprehension?
Both fit in the same shape you've been building all week:
# Skeleton: [transform for x in xs if filter]
result = [w.upper() for w in words if len(w) > min_len]Read it left to right: "uppercase each word, for each word in words, if its length is greater than min_len." The filter runs first — only passing words reach .upper().
def uppercase_long_words(words: list, min_len: int) -> list:
return [w.upper() for w in words if len(w) > min_len]Four moves fused into one expression: iterate, filter, transform, collect.
What if min_len is 0 — does every word pass and get uppercased?
Every non-empty string has length at least 1, so len(w) > 0 is true for all of them. Empty strings fail the filter (0 is not greater than 0), so they drop out. That's the subtle power of strict inequality — it handles the empty-string edge case for free.
And if min_len is really large — say 100 — the comprehension returns [] because nothing passes?
Right. Too-strict filter → empty result. No crash, no special case. That's the same graceful degradation you've seen all week: comprehensions handle empty collections and empty filter-passing sets uniformly.
This one function uses every comprehension technique from the week — list, filter, transform. If I understand this shape, I understand comprehensions.
That's the whole week in one line. The same mental shape — expression, for, if — scales to dict and set comprehensions, to nested loops, to generator expressions. Master this one pattern and the rest are shape variations.
TL;DR: [f(x) for x in xs if cond(x)] is the universal shape — filter, then transform, in one expression.
if cond gates which items reach f(x)f(x) runs only on passing items| Goal | Shape |
|---|---|
| Transform every item | [f(x) for x in xs] |
| Filter and transform | [f(x) for x in xs if c] |
| Build a dict | {k: v for k, v in ps} |
| Dedupe unique values | {x for x in xs} |
Same mental model across all four — only the brackets and output shape change.
Write `uppercase_long_words(words, min_len)` that returns a list of uppercased words whose length is strictly greater than `min_len`. Use a single list comprehension with an `if` clause.
Tap each step for scaffolded hints.
No blank-editor panic.