We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Laziness, Iteration and Pipelines step 14 of 14
zip(strict=True) and the silent-truncation bug
zip() stops at the shortest argument and says nothing about it.
That is a data-corruption bug that no test with equal-length fixtures will ever
find. Names and scores drift out of sync by one row somewhere upstream, zip
silently drops the tail, the report renders, the numbers look plausible, and
nobody notices for a quarter. There is no exception, no warning, and no log
line — the failure mode is a smaller correct-looking answer.
strict=True (3.10) turns it into a ValueError at the point the shorter
argument runs out. Make that your default for any zip over two things that are
supposed to correspond. Reserve plain zip for the cases where truncation is
the intent, and say so in a comment when you do.
What to write
def align(names: Sequence[str], scores: Sequence[float]) -> dict[str, float]
Pair each name with its score. On a length mismatch — in either direction —
raise LengthMismatch (a ValueError subclass, provided) with the message:
length mismatch: names=<len(names)>, scores=<len(scores)>
Both numbers, always. ValueError: zip() argument 2 is shorter than argument 1
is technically accurate and useless at 3am: it does not tell you how far off
you are, which is the first thing you want when deciding whether a row was
dropped or a whole file was truncated.
Chain the original: raise LengthMismatch(...) from exc. The __cause__ keeps
zip’s own message in the traceback, so the reader can see both the domain
framing and the mechanical cause.
Duplicate names are not an error — later entries win, exactly as dict()
would. Empty inputs on both sides produce an empty mapping and no error.
solve is provided: it calls align and turns a LengthMismatch into the
report’s error field.
Why Sequence
len() is in the message, so the parameter must be something with a length.
Annotating Iterable[str] and then calling len() on it is a type error, and
“just call list() first” quietly reintroduces the materialisation this track
spends its time avoiding. Pick the ABC that matches what the body actually
does.
Loading visualization…
Stuck?
Python reference solution
Sign in to attempt this problem and reveal the reference solution.