You want a function that takes a list of transactions and a threshold, and returns a list of the transactions whose amount is over the threshold — sorted biggest first. Where do you start?
Two things to do — filter by amount, then sort. That's a comprehension and a sorted() call.
Exactly — two known moves. Compose them. Start with the filter — a comprehension picks out only the rows above the threshold:
high = [t for t in txns if t["amount"] > limit]Then wrap the result in sorted() with a key and reverse=True. One line, two moves.
Does the order matter — could I sort first, then filter?
Both orders give the same final list, but filtering first is cheaper — you sort a smaller list. When composing, do the cheap shrinking work before the expensive ordering work.
The two-pattern combo feels elegant, but my eyes have to jump around to read it. Is it worth it?
For two moves, yes — it's still readable. For three or more, break it into named intermediate variables. Clarity wins over one-liner satisfaction:
def high_value_expenses(txns, limit):
high = [t for t in txns if t["amount"] > limit]
return sorted(high, key=lambda t: t["amount"], reverse=True)So composition is less about clever syntax and more about stacking small, known moves in the right order.
Exactly. Every function from now on is two or three known moves composed together. The skill is seeing which moves fit, not writing new ones.
TL;DR: two familiar moves stacked — filter with a comprehension, sort the result.
[t for t in txns if t["amount"] > limit]sorted(..., key=lambda t: t["amount"], reverse=True)| Moves | Style |
|---|---|
| 1 | inline |
| 2 | inline or named — pick readable |
| 3+ | named intermediate variables |
Use intermediate names when the one-liner forces too many nested () or []. Clarity wins.
Write `high_value_expenses(txns, limit)` that returns transactions whose amount is strictly greater than limit, sorted largest first.
Tap each step for scaffolded hints.
No blank-editor panic.
You want a function that takes a list of transactions and a threshold, and returns a list of the transactions whose amount is over the threshold — sorted biggest first. Where do you start?
Two things to do — filter by amount, then sort. That's a comprehension and a sorted() call.
Exactly — two known moves. Compose them. Start with the filter — a comprehension picks out only the rows above the threshold:
high = [t for t in txns if t["amount"] > limit]Then wrap the result in sorted() with a key and reverse=True. One line, two moves.
Does the order matter — could I sort first, then filter?
Both orders give the same final list, but filtering first is cheaper — you sort a smaller list. When composing, do the cheap shrinking work before the expensive ordering work.
The two-pattern combo feels elegant, but my eyes have to jump around to read it. Is it worth it?
For two moves, yes — it's still readable. For three or more, break it into named intermediate variables. Clarity wins over one-liner satisfaction:
def high_value_expenses(txns, limit):
high = [t for t in txns if t["amount"] > limit]
return sorted(high, key=lambda t: t["amount"], reverse=True)So composition is less about clever syntax and more about stacking small, known moves in the right order.
Exactly. Every function from now on is two or three known moves composed together. The skill is seeing which moves fit, not writing new ones.
TL;DR: two familiar moves stacked — filter with a comprehension, sort the result.
[t for t in txns if t["amount"] > limit]sorted(..., key=lambda t: t["amount"], reverse=True)| Moves | Style |
|---|---|
| 1 | inline |
| 2 | inline or named — pick readable |
| 3+ | named intermediate variables |
Use intermediate names when the one-liner forces too many nested () or []. Clarity wins.