Python · Functional Python

Iterators & Generators — Practice Questions

50 questions. Try each one yourself before checking the answer.

Q1iter()Easy

Given numbers = [1, 2, 3], create an iterator from it using iter() and print its type().

Q2next()Easy

Using the iterator from Q1, call next() on it three times, printing each result.

Q3StopIterationEasy

Exhaust a 2-item iterator with two next() calls, then call next() a third time and catch the StopIteration it raises.

Q4next() with DefaultEasy

Using an exhausted iterator, call next(iterator, "done") to get a default value instead of a StopIteration error.

Q5yieldEasy

Write a generator function count_to_three() that yields 1, then 2, then 3.

Q6GeneratorsEasy

Call count_to_three() (from Q5) WITHOUT looping over it, and print the result directly to show it's a generator object, not the yielded values.

Q7Generator ExpressionsEasy

Create a generator expression for the squares of 1 to 5 (using () instead of []), then convert it to a list to see its values.

Q8Iterating a GeneratorEasy

Manually call next() on the generator returned by count_to_three() (from Q5) twice, then finish the rest with a for loop.

Q9Iterable vs IteratorEasy

Given numbers = [1, 2, 3], show that a for loop works directly on the LIST, but you can also manually build an iterator from it with iter() first.

Q10sum() with GeneratorEasy

Use a generator expression directly inside sum() to add up the squares of 1 to 5, without ever building a list.

Q11yieldMedium

Write a generator function squares_up_to(n) that yields the square of each number from 1 to n, using a loop inside.

Q12Infinite GeneratorsMedium

Write an infinite generator count_up_from(start) using while True and yield, then manually pull only the first 5 values with next().

Q13Generator ExpressionsMedium

Compare a list comprehension [n for n in range(5)] and a generator expression (n for n in range(5)) — print both and their types, and explain the difference in a comment.

Q14max() with GeneratorMedium

Given words = ["apple", "kiwi", "banana", "fig"], use a generator expression inside max() with a key to find the longest word without a separate list.

Q15Generator PipelinesMedium

Given numbers = range(1, 11), build one generator expression that filters even numbers, then feed it into another generator expression that doubles each — a simple two-stage pipeline.

Q16list() on GeneratorsMedium

Write a generator function countdown(n) that yields from n down to 1, then convert its output to a list using list().

Q17Custom Iterator ClassMedium

Build a class Counter implementing the iterator protocol (__iter__ returning self, __next__ counting up and raising StopIteration past a limit).

Q18yield vs returnMedium

Write two versions of a function that produces the numbers 1 to 5: one using return (builds and returns a full list), one using yield (a generator). Compare their type().

Q19Generators with ConditionsMedium

Write a generator function positive_only(numbers) that yields only the positive numbers from a given list.

Q20Multiple yieldsMedium

Write a generator function name_and_greeting(name) that first yields the name, then yields a greeting built from it — showing a generator can yield DIFFERENT kinds of values in sequence.

Q21Real-WorldMedium

Write a fibonacci(n) generator that yields the first n Fibonacci numbers lazily, one at a time.

Q22Real-WorldMedium

Write an even_numbers_up_to(n) generator, then use it directly inside sum() to compute the total of all even numbers up to n without building a list.

Q23Real-WorldMedium

Write a read_lines_lazily(filename) generator that opens a file and yields one stripped line at a time (tying back to the File Handling module).

Q24Real-WorldMedium

Write a batches(items, size) generator that yields successive chunks (as lists) of a given size from a longer list.

Q25Real-WorldMedium

Write an infinite natural_numbers() generator, then combine it with itertools.islice() to grab just the first 5 values.

Q26Real-WorldMedium

Write a primes() generator that yields prime numbers indefinitely, testing each candidate as it goes.

Q27Lazy EvaluationMedium

Add a print("generating...") statement inside a generator function, then show that it doesn't print when the generator is CREATED — only when its values are actually consumed.

Q28Real-WorldMedium

Write a words_from_text(text) generator that yields one word at a time from a sentence, using .split() internally.

Q29DebuggingMedium

The following code prints a generator object instead of the numbers 1-3. Find and fix the bug.

def count_to_three():
    yield 1
    yield 2
    yield 3
 
print(count_to_three())
Q30FormattingMedium

Write a generator formatted_prices(prices) that yields each price formatted as currency ("$X.XX"), then print each yielded string.

Q31Custom IteratorHard

Build a Countdown class implementing the full iterator protocol, counting down from n to 1, and demonstrate it in both a for loop and manual next() calls.

Q32yield fromHard

Write a generator all_numbers() that delegates to two smaller generators, first_half() and second_half(), using yield from for each.

Q33itertools.isliceHard

Given an infinite count_up_from(start) generator, use itertools.islice(generator, start, stop) to grab a SLICE from the middle of an infinite sequence (not just the first N).

Q34Memory EfficiencyHard

Using sys.getsizeof(), compare the memory footprint of range(1000000) versus list(range(1000000)), demonstrating why lazy sequences scale better.

Q35Generator ExhaustionHard

Create a generator, iterate over it fully once with a for loop, then try to iterate over the SAME generator object again, showing it yields nothing the second time.

Q36Recursive GeneratorsHard

Write a recursive generator flatten(nested) that yields every element from an arbitrarily nested list, using yield from for the recursive case.

Q37Custom IteratorHard

Build a MyRange class that fully replicates the behavior of the built-in range(start, stop, step), implementing __iter__/__next__.

Q38Generator PipelinesHard

Build a 3-stage generator pipeline over numbers = range(1, 21): filter multiples of 3, square each, then keep only results under 200 — all lazily chained.

Q39Lazy EvaluationHard

Prove that a generator expression evaluates its condition LAZILY by combining it with a function that has a visible side effect (a print), and showing the prints are interleaved with consumption, not all upfront.

Q40DebuggingHard

The following code is supposed to sum values from TWO separate uses of the same generator, but the second sum is always 0. Find and fix the bug.

def numbers():
    yield 1
    yield 2
    yield 3
 
gen = numbers()
total1 = sum(gen)
total2 = sum(gen)
print(total1, total2)
Q41Mini-ProjectMini-Project

Build a "Fibonacci Generator Tool". Ask the user how many terms they want, then print them lazily using a generator (never storing the full sequence in a list).

Q42Mini-ProjectMini-Project

Build a "Log Line Filter". Write a generator that reads a log file lazily and yields only lines containing "ERROR".

Q43Mini-ProjectMini-Project

Build a "Batch Processor". Given a large list of records, write a generator yielding fixed-size batches, and process (print) each batch as if sending it to an API one chunk at a time.

Q44Mini-ProjectMini-Project

Build a fully-featured custom EvenRange iterator class that yields only even numbers between a start and stop, implementing the complete iterator protocol.

Q45Mini-ProjectMini-Project

Build a "Prime Finder Tool". Ask the user how many primes they want, and use an infinite primes() generator combined with itertools.islice() to get exactly that many.

Q46InterviewInterview

Explain the precise difference between an "iterable" and an "iterator": every iterator is iterable, but not every iterable is an iterator. Demonstrate with a list.

Q47InterviewInterview

Explain why generators are the right choice for processing huge datasets (e.g. a 10GB log file), tying it back to the lazy-evaluation and memory-footprint concepts from earlier in this module.

Q48InterviewInterview

Demonstrate a REAL bug caused by generator exhaustion: a function that accepts a generator and iterates over it TWICE (once to count, once to process), silently processing nothing the second time. Fix it by converting to a list first.

Q49InterviewInterview

Explain a practical use case for yield from: delegating work to sub-generators when flattening a tree-like structure, and why it's cleaner than manually looping and re-yielding.

Q50CapstoneInterview

Build an "Iterator & Generator Mastery Report" — the most complete demonstration in this module. Combine: a custom iterator class, a generator function using yield, a chained generator expression pipeline, and itertools.islice on an infinite generator — printing labeled results from each.

Still stuck on something?

Book a free 1-on-1 session and we'll work through it together.

Book a Free Session