Iterators & Generators: Practice Questions
100 questions. Try each one yourself before checking the answer.
Short on time? Filter by Must Do for the 25 questions that cover this topic on their own.
Turn a list into an iterator with iter() and pull values from it one at a time with next().
Show what happens when an iterator runs out.
Use next() with a default so exhaustion returns a value instead of raising.
Show that lists, strings, tuples, sets, dictionaries and ranges are all iterable.
Rewrite a for loop using only iter(), next() and while, to show what for does underneath.
Show that an iterator can only be walked once.
Show that two iterators over the same list keep separate positions.
Show that a file object is its own iterator — the Topic 12 behaviour, explained.
Show the difference between an iterable and an iterator by checking for __iter__ and __next__.
Make your own class iterable in the simplest way: return an iterator from __iter__.
Write a full iterator class with __iter__ and __next__.
Show the difference between an iterator class that can be reused and one that cannot.
Write your first generator function using yield.
Show a generator being used in a for loop and converted to a list.
Show that a generator pauses and resumes, by printing on both sides of the yield.
Compare a generator with an ordinary function that builds and returns a list.
Prove that a generator only does work when asked.
Write a generator with no end and take values from it safely.
Write a generator expression and show it is a generator, not a list.
Use a generator expression directly inside sum(), max() and min().
Add a condition to a generator expression to filter values.
Show that a generator remembers its local variables between calls.
Use yield from to hand off to another iterable.
Make a class iterable by writing __iter__ as a generator.
Write a generator that yields cleaned lines from a file.
Write a Fibonacci generator that can produce as many terms as asked for.
Write a prime number generator and take the first N primes from it.
Chain three generators into a pipeline where each stage feeds the next.
Build a numeric pipeline and prove only the requested values are computed.
Write generators that filter and transform, then combine them.
Use yield from recursively to flatten an arbitrarily nested list.
Walk a nested dictionary structure with yield from, producing paths to every leaf.
Write a generator that produces running totals from a stream of numbers.
Write a sliding-window generator.
Write a chunking generator that yields fixed-size batches.
Write a generator that yields only values it has not seen before.
Show that a generator can return a value, and how to read it.
Capture a generator's return value using yield from.
Use .close() to stop a generator early, and try/finally to clean up.
Use .send() to pass a value back into a paused generator.
Use itertools.count, islice and takewhile for infinite sequences.
Use itertools.chain, cycle and repeat.
Use itertools.groupby to group consecutive equal items.
Measure the memory difference between a list and a generator.
Write a generator that yields parsed records from a CSV file.
Write an iterator class that produces values without storing them.
Support reversed() on your own class.
Build a reusable pipeline helper that applies a list of stages.
Write a generator that merges two already-sorted streams.
Nest generator expressions and use one inside another.
Process a log file as a stream, reporting counts without loading the file.
Build a paginator that yields pages of results from a long sequence.
Simulate a sensor producing readings forever, and monitor it until a condition is met.
Build a grep-like tool that yields matching lines with their numbers.
Stream a large CSV, validating rows and reporting bad ones without stopping.
Build a moving-average generator for a stream of readings.
Build an ID generator that produces unique identifiers on demand.
Build a retry generator that yields attempt numbers with increasing waits.
Walk a nested folder-like structure with yield from.
Build a progress-reporting generator that wraps any iterable.
Stream two files and report which lines differ, without loading either.
Build a word-frequency counter that streams a large text.
Sample every nth item from a stream, and take a random sample from a stream of unknown length.
Build a batching processor that sends records to a fake API in groups.
Build a generator that produces a calendar-like sequence of working days.
Use itertools to build a round-robin task assigner.
Build a data-cleaning pipeline with a report of what each stage removed.
Build a generator that yields running statistics over a stream.
Build a generator-based state machine that consumes a stream of events.
Build a generator that reads records and yields only changes from the previous one.
This report shows a total of zero. Explain why and give two fixes.
def squares(limit):
for n in range(1, limit + 1):
yield n ** 2
values = squares(5)
print(f"values: {list(values)}")
print(f"total: {sum(values)}")
print(f"count: {sum(1 for _ in values)}")Show the operations that do not work on a generator, and what to use instead.
Explain why this generator expression produces surprising results.
multiplier = 2
doubled = (n * multiplier for n in [1, 2, 3])
multiplier = 10
print(list(doubled))Show what happens when a generator's source is consumed elsewhere.
Show what happens when a generator is created inside a loop rather than outside it.
Show what happens when StopIteration is raised inside a generator.
Measure the real memory and time difference on a large workload.
Show the bug caused by returning self from __iter__ when the class holds the position.
Show the ways an infinite generator can hang a program, and how to guard against them.
Show that a return inside a generator ends it silently, and how that hides bugs.
Show that modifying a list while a generator walks it causes trouble.
Show what happens to try/finally cleanup when a generator is abandoned rather than exhausted.
Compare a generator expression with the equivalent list operation and say when each wins.
Show that a deep pipeline still uses constant memory, and what its real cost is.
Show three cases where reaching for a generator is the wrong choice.
Build a Streaming Log Analyser: read, parse, filter and summarise a log file through a generator pipeline that never loads it.
Build a CSV Processing Pipeline with composable stages and a summary of what each stage dropped.
Build a Number Sequence Toolkit of infinite generators with a shared take helper.
Build a Paginated Search over a large dataset that only computes the page requested.
Build a Sensor Monitoring System with infinite sensor streams, alerting and a live summary.
Build a File Search Tool that streams several files and reports matches with context.
Build a Batch Job Runner that streams work, batches it, retries failures and reports.
Build a Nested Structure Walker that flattens any depth of nesting and reports on it.
Build a Streaming Statistics Engine that reports without ever storing the data.
Build a Text Processing Pipeline producing a full report from a streamed document.
Explain the difference between an iterable, an iterator and a generator, with code for each.
Explain exactly what a for loop does, and what that means for your own classes.
Give a clear rule for choosing between a generator and a list, with the trade-offs.
Explain lazy evaluation: what it means, what it buys, and what it costs.
Capstone. Build a Generator Toolkit Report demonstrating the whole topic: the iterator protocol by hand, a class made iterable, generator functions and expressions, yield from, an infinite source, a multi-stage pipeline, itertools, .send(), cleanup with close(), and a memory comparison.
Still stuck on something?
Book a free 1-on-1 session and we'll work through it together.
Book a Free Session