Python Iterators and Generators Quiz: itertools Practice Test
Test yourself with 12 questions and three programs on Python iterators, generators, generator expressions, itertools, functools and lazy pipelines.
- Course: Python study plan
- Module: Iterators, generators and itertools
- Kind: Checkpoint — cleared at 70%
- Reading time: 25 min
- Runtime: CPython 3.11
Checkpoint — Iterators, generators and itertools is the checkpoint that closes the Iterators, generators and itertools module: a graded quiz and whole-program exercises, passed at 70%.
Instructions
This checkpoint covers the whole module: the iteration protocol with iter, next and StopIteration, generators with yield, yield from and laziness, generator expressions and the short-circuit consumers, the itertools toolkit with groupby's consecutive-run rule and the combinatoric generators, functools and operator, and the design of lazy pipelines.
How it works. Twelve questions and three programs. You need 70% on the questions and every program accepted to clear the module. You can retake it as often as you like; your best score counts.
Before you start, make sure you can answer these from memory:
- What is the difference between an iterable and an iterator, and which one is
zip(a, b)? - What happens the first time a generator function is called, and when does its body run?
- Why is
sum(x for x in xs)preferable tosum([x for x in xs]), and when is a list comprehension still right? - What does
groupbydo on unsorted input? - What are
product,permutationsandcombinations, and how do their sizes grow? - What does
@cacherequire of a function? - In a pipeline, which stage should handle a malformed record, and why?
The three programs are a run-length codec built on groupby, a subset-sum search over combinations that stops at the first hit, and a log pipeline of generator stages that parses, filters and aggregates in one pass.
Common questions
What is the difference between an iterable and an iterator, and which one is zip(a, b)?
An iterable is anything iter() accepts and can hand out fresh iterators, like a list or a range; an iterator produces the values through __next__ and is one-shot. zip(a, b) returns an iterator, so a second pass over the same zip object yields nothing.
What happens when a generator function is called?
None of its body runs: the call returns a generator object. The body runs only when a value is requested by next() or a loop, executing to the next yield and suspending there, so an error inside it surfaces at that next() rather than at the call.
What does @cache require of a function?
The function must be pure, meaning the same arguments always give the same result with no side effects that matter, and every argument must be hashable, because the arguments form the cache key. A list argument raises TypeError; pass a tuple instead.
Exercises
Run-length codec with groupby
Each line is E <text> or D <code>. Encode with itertools.groupby — each run becomes the character followed by its count (aaabcc → a3b1c2). Decode by scanning the code: a character followed by one or more digits (a generator that yields the expanded characters, joined at the end). Text after the command is taken literally.
Input: lines. Output: one line per input line (an empty result prints (empty)).
E aaabcc
D a3b1c2
prints
a3b1c2
aaabccSubset sum, first hit
Read a target and a line of positive integers. Search the combinations of indexes by increasing size (1, 2, …, all) with itertools.combinations, in the order combinations produces them, and stop at the first combination whose values sum to the target — using next over a generator expression chained across sizes with itertools.chain.from_iterable. Print the chosen values or none.
Input: the target, then a line of integers. Output: found <values> or none.
9
2 7 5 4
prints
found 2 7Log pipeline
Process log lines ip method path status size through generator stages: read_lines (strip, drop blank), parse (yield a tuple with status and size as ints; skip lines with the wrong field count or non-integer fields), only(method="GET"), and a single-pass summarise that returns status counts, path counts and total bytes. Print status <code>: <n> in ascending order, bytes <total>, and top <path> (most requests, ties alphabetical) or top none.
Input: lines. Output: the summary.
1.1.1.1 GET /a 200 100
1.1.1.2 POST /a 200 50
1.1.1.1 GET /b 404 0
bad line
prints
status 200: 1
status 404: 1
bytes 100
top /aIn this module: Iterators, generators and itertools
- The iteration protocol — iter, next and StopIteration
- Generators — functions that yield
- Generator expressions — lazy comprehensions
- itertools — the iterator toolkit
- functools and operator — the function toolkit
- Lazy pipelines — a worked log-processing example
- Checkpoint — Iterators, generators and itertools (this lesson)
← Lazy pipelines — a worked log-processing example · Modules and imports — files, namespaces and sys.modules →