Last week you used a comprehension to filter — keep the rows that match. Today, use it to transform — pull one field out of each dict. What changes?
Instead of [t for t in txns if ...], the expression before for becomes t["amount"] — the thing I want in the output, not the whole dict?
Exactly right. The position before for is the "what ends up in the new list" slot. Swap t for t["amount"] and you've shifted the comprehension from filter to transform:
[t["amount"] for t in txns]For a list of transaction dicts, this returns a plain list of floats. Same syntax, different shape going in and out.
So the expression part doesn't have to be a variable — it can be any computation?
Any expression. [t["amount"] * 1.1 for t in txns] adds 10% to every amount. [t["category"].upper() for t in txns] uppercases every category. The comprehension applies the expression to each element once.
And if I need to filter and transform? Can I put both in one line?
Yes. [t["amount"] for t in txns if t["category"] == "Food"] — filter first, transform second, one pass:
[t["amount"] for t in txns if t["category"] == "Food"]The if at the end gates which items reach the expression. Both halves are optional — you can have just a transform, just a filter, or both.
So one shape — [expr for item in list if cond] — covers three different operations, depending on which pieces I use.
That's the whole idea. Comprehensions are one of the reasons Python reads like English. Once the shape is in your head, every "new list from old list" problem fits the same template.
TL;DR: [expression for item in iterable] — one line, one new list.
if cond at the end| Goal | Shape |
|---|---|
| Filter only | [t for t in xs if cond] |
| Transform only | [t["amount"] for t in xs] |
| Both | [t["amount"] for t in xs if cond] |
Pick the pieces you need. The comprehension template scales from one operation to both.
Write `extract_amounts(txns)` that returns a list of the `"amount"` values from each transaction dict. Empty input returns an empty list.
Tap each step for scaffolded hints.
No blank-editor panic.
Last week you used a comprehension to filter — keep the rows that match. Today, use it to transform — pull one field out of each dict. What changes?
Instead of [t for t in txns if ...], the expression before for becomes t["amount"] — the thing I want in the output, not the whole dict?
Exactly right. The position before for is the "what ends up in the new list" slot. Swap t for t["amount"] and you've shifted the comprehension from filter to transform:
[t["amount"] for t in txns]For a list of transaction dicts, this returns a plain list of floats. Same syntax, different shape going in and out.
So the expression part doesn't have to be a variable — it can be any computation?
Any expression. [t["amount"] * 1.1 for t in txns] adds 10% to every amount. [t["category"].upper() for t in txns] uppercases every category. The comprehension applies the expression to each element once.
And if I need to filter and transform? Can I put both in one line?
Yes. [t["amount"] for t in txns if t["category"] == "Food"] — filter first, transform second, one pass:
[t["amount"] for t in txns if t["category"] == "Food"]The if at the end gates which items reach the expression. Both halves are optional — you can have just a transform, just a filter, or both.
So one shape — [expr for item in list if cond] — covers three different operations, depending on which pieces I use.
That's the whole idea. Comprehensions are one of the reasons Python reads like English. Once the shape is in your head, every "new list from old list" problem fits the same template.
TL;DR: [expression for item in iterable] — one line, one new list.
if cond at the end| Goal | Shape |
|---|---|
| Filter only | [t for t in xs if cond] |
| Transform only | [t["amount"] for t in xs] |
| Both | [t["amount"] for t in xs if cond] |
Pick the pieces you need. The comprehension template scales from one operation to both.