We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Stdlib Mastery step 13 of 55
groupby: summarise rows without losing half of them
Summarise (key, value) rows into key -> (count, sum) using
itertools.groupby.
def summarise(rows: list[tuple[str, int]]) -> dict[str, tuple[int, int]]: ...
def solve(rows: list[tuple[str, int]]) -> dict[str, tuple[int, int]]: ...
The input is not sorted, and the same key appears in several runs. The result must have exactly one entry per distinct key, with the total count and total sum across every occurrence.
Both of groupby‘s failure modes are silent, and the tests here are built
to expose them.
It does not group, it run-length encodes. A new group starts every time the
key differs from the previous element. Feed it unsorted data and you get
[('a', [...]), ('b', [...]), ('a', [...])] — a duplicate key, no exception.
Build a dict from that and the later run overwrites the earlier one; records
vanish with no error. The test rows interleave keys precisely so a no-sort
solution loses data.
The group iterator is a view over the shared source. Advancing the outer
groupby invalidates the group you were handed. list(groupby(data, key))
returns the right keys with empty groups — so a test that asserts on keys
passes while every record is gone. Drain each group inside the loop body,
before asking for the next one.
Your submission must pass mypy --strict. Use a named, annotated key
function rather than a lambda: with a lambda the group key usually degrades to
Any, which then disables checking on the dict you index with it. A named key
function also makes it impossible to pass one key to sorted and a different
one to groupby, which is a common near-miss that works on fixtures and
breaks on real data.
The values are tuples, not lists. The harness compares container types exactly.
Loading visualization…
Stuck?
Python reference solution
Sign in to attempt this problem and reveal the reference solution.