Your quality-control protocol flags the top 5 respondents by outcome for manual review before including them in the analysis. In Week 2, you built compute_outcome_per_respondent with a for loop and append. Is there a more compact way?
respondents_to_json from Day 21 showed list comprehensions briefly. [r for r in respondents if condition] — that's the filter. Then I'd sort the result by outcome descending and slice the top N.
Exactly. List comprehensions collapse the loop-and-append pattern into one line. Filter first with if r.get("outcome") is not None, then sort with sorted(key=...), then slice:
valid = [r for r in respondents if r.get("outcome") is not None]
top = sorted(valid, key=lambda r: r["outcome"], reverse=True)[:n]What's lambda r: r["outcome"]? I've seen lambda but never written one.
A lambda is a tiny anonymous function written inline. lambda r: r["outcome"] is equivalent to def get_outcome(r): return r["outcome"]. The sorted function uses it as the sort key — every respondent dict is passed through the lambda and sorted by the outcome value it returns:
def top_respondents_by_outcome(respondents: list, n: int = 5) -> list:
valid = [r for r in respondents if r.get("outcome") is not None]
top = sorted(valid, key=lambda r: r["outcome"], reverse=True)[:n]
print(f"Top {n} of {len(valid)} valid respondents")
return topOne comprehension to filter, one sorted call to rank, one slice to limit. Three operations, one expression. The for loop version would have been twelve lines.
Welcome to data wrangling at research scale. The lambda is just an inline function — if it grows complex, name it. But for a sort key, inline is cleaner.
I can see the Week 4 capstone shape now — top_respondents_by_outcome is the first step in the outlier-flagging logic.
r.get("outcome") is not None is safer than r["outcome"] because .get returns None for missing keys without raising KeyError. However, is not None also passes through 0.0 — a zero outcome is valid, not missing. That distinction matters for clinical trials where zero is a meaningful result.
[expr for item in collection if condition]Equivalent to: create empty list, loop, check condition, append.
sorted(items, key=lambda x: x["field"], reverse=True)key is called on each item to produce the sort value. reverse=True sorts descending (largest first).
lambda arg: expression is an anonymous one-line function. Use for short sort keys and filters. For anything longer, write a named def.
lst[:n] returns the first n items. After sorting descending, [:5] gives the top 5.
Your quality-control protocol flags the top 5 respondents by outcome for manual review before including them in the analysis. In Week 2, you built compute_outcome_per_respondent with a for loop and append. Is there a more compact way?
respondents_to_json from Day 21 showed list comprehensions briefly. [r for r in respondents if condition] — that's the filter. Then I'd sort the result by outcome descending and slice the top N.
Exactly. List comprehensions collapse the loop-and-append pattern into one line. Filter first with if r.get("outcome") is not None, then sort with sorted(key=...), then slice:
valid = [r for r in respondents if r.get("outcome") is not None]
top = sorted(valid, key=lambda r: r["outcome"], reverse=True)[:n]What's lambda r: r["outcome"]? I've seen lambda but never written one.
A lambda is a tiny anonymous function written inline. lambda r: r["outcome"] is equivalent to def get_outcome(r): return r["outcome"]. The sorted function uses it as the sort key — every respondent dict is passed through the lambda and sorted by the outcome value it returns:
def top_respondents_by_outcome(respondents: list, n: int = 5) -> list:
valid = [r for r in respondents if r.get("outcome") is not None]
top = sorted(valid, key=lambda r: r["outcome"], reverse=True)[:n]
print(f"Top {n} of {len(valid)} valid respondents")
return topOne comprehension to filter, one sorted call to rank, one slice to limit. Three operations, one expression. The for loop version would have been twelve lines.
Welcome to data wrangling at research scale. The lambda is just an inline function — if it grows complex, name it. But for a sort key, inline is cleaner.
I can see the Week 4 capstone shape now — top_respondents_by_outcome is the first step in the outlier-flagging logic.
r.get("outcome") is not None is safer than r["outcome"] because .get returns None for missing keys without raising KeyError. However, is not None also passes through 0.0 — a zero outcome is valid, not missing. That distinction matters for clinical trials where zero is a meaningful result.
[expr for item in collection if condition]Equivalent to: create empty list, loop, check condition, append.
sorted(items, key=lambda x: x["field"], reverse=True)key is called on each item to produce the sort value. reverse=True sorts descending (largest first).
lambda arg: expression is an anonymous one-line function. Use for short sort keys and filters. For anything longer, write a named def.
lst[:n] returns the first n items. After sorting descending, [:5] gives the top 5.
Theo needs the top N respondents by outcome score for manual quality review. Write `top_respondents_by_outcome(respondents, n=5)` using a list comprehension to filter out respondents with missing outcomes, sorted descending by outcome, sliced to the top N.
Tap each step for scaffolded hints.
No blank-editor panic.