We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Stdlib Mastery step 4 of 55
defaultdict: group rows, hand back a plain dict
Group (key, value) rows into key -> [values], preserving first-seen key
order, and return a container that behaves like a dict to every caller.
Implement two functions:
def group_by_key(rows: list[tuple[str, int]]) -> dict[str, list[int]]: ...
def solve(
rows: list[tuple[str, int]], probe: str
) -> tuple[list[tuple[str, list[int]]], str, str]: ...
solve exercises group_by_key and reports what it got back, as a 3-tuple:
-
list(grouped.items())— taken after the probe below, in first-seen key order. -
type(grouped).__name__— must be"dict". -
"KeyError"ifgrouped[probe]raises,"returned"if it hands back a value.
The production consequence. defaultdict inserts on read. A
defaultdict that escapes a function exports that behaviour to every caller:
a membership test written if grouped[k]: grows the mapping forever, a
serialiser sees the dict change size while iterating, and a caller who
reasonably expects KeyError gets an empty list instead. The annotation
-> dict[str, list[int]] will not warn you, because a defaultdict is a
dict as far as the type system is concerned. The invariant “no
insert-on-read” is not expressible in the signature, so it has to be enforced
by the code: build with defaultdict, return dict(grouped).
Notice that the probe happens before the items snapshot. If you return the
defaultdict itself, probing an absent key inserts an entry and the item list
changes too — the same bug caught twice.
Your submission must pass mypy --strict. defaultdict(list) on its own is a
var-annotated error (“Need type annotation”) — the most useful error in the
module, because it forces you to state the shape of the grouping.
Returns a tuple, and the first element is a list of tuples. The harness compares container types exactly.
Stuck?
Python reference solution
Sign in to attempt this problem and reveal the reference solution.