PYTHON & CODING · QUESTION 77
What is the difference between an iterable, an iterator, and a generator?
On this page
An iterable can produce an iterator, typically through `iter()`. An iterator implements `__next__()` and yields one item at a time until `StopIteration`. A generator is a convenient iterator created by a generator function using `yield` or by a generator expression. Generators are lazy and can save memory, but they are usually consumed once.
LET'S MAKE IT SIMPLE
First, the idea in plain English
A list is iterable because a loop can request items from it. The loop gets an iterator that remembers where it is and returns the next item when asked. A generator creates those values as the program needs them rather than building the entire result in memory first.
A USEFUL COMPARISON
Picture it this way
An iterable is like a cookbook that can provide a fresh reading order; an iterator is one reader’s current bookmark; a generator prepares each page when requested. A generator can be efficient for large sequences, but once the reader reaches the end, that iterator is exhausted.
FOLLOW THE JOURNEY
Iteration requests values one at a time
Show how an iterable supplies an iterator and a generator yields values lazily.
This simplified visual highlights the main relationships. In practice, the exact design depends on the requirements; The loop uses this signal to finish cleanly.
A loop calls iter on an iterable, repeatedly requests next values from an iterator, and stops when the iterator raises StopIteration; a generator provides values through yield.
How to read this visual
This simplified visual highlights the main relationships. In practice, the exact design depends on the requirements; The loop uses this signal to finish cleanly.
UNDER THE HOOD
How it works, step by step
Create iterator
Call `iter()` on an iterable such as a list or generator.
Why it matters: The iterator stores the current traversal state.
Request next value
Call `next()` to receive one item.
Why it matters: Values can be consumed without materializing the full result.
Stop at exhaustion
The iterator raises StopIteration when no values remain.
Why it matters: The loop uses this signal to finish cleanly.
OUTSIDE THE TEXTBOOK
A practical example
A log-processing job reads a large file line by line with a generator instead of loading every line into a list. The consumer handles each line and keeps only the current state, reducing memory use. If it needs a second pass, it opens a new file iterator.
GO A LITTLE DEEPER
Technical details that matter
- A generator function pauses at `yield` and resumes with its local state intact on the next request.
- Generator expressions use parentheses and can be passed directly to consuming functions.
- A generator object is generally single-pass; calling the generator function again creates a new generator.
def squares(limit):
for number in range(limit):
yield number * number
for value in squares(3):
print(value)The generator computes one square each time the loop requests a value. The output is 0, 1, and 4; the complete result is never stored in a list.
MAKE A GOOD CHOICE
When is this useful?
- Processing large files or streams incrementally.
- Creating pipelines where each stage transforms one item at a time.
- Avoiding unnecessary intermediate collections.
Use a list when you need repeated indexing or multiple passes over a small result. Materialize a generator explicitly when reuse is required.
WATCH OUT FOR
Common misunderstandings
- Calling every iterable an iterator.
- Expecting a generator to restart after it is exhausted.
- Using lazy iteration when the code needs random access or repeated traversal.
REAL-WORLD TRADE-OFFS
Limitations and failure cases
- Generators can be consumed only once unless recreated.
- Lazy execution can defer errors until iteration.
- A generator may retain resources or state while it is active.
WHAT TO REMEMBER
Key takeaways
- 1Iterables create iterators; iterators yield values with `next()`.
- 2Generators are concise, lazy iterators.
- 3Choose lazy or materialized data based on memory and reuse needs.
PRACTICE THE FOLLOW-UP
What might an interviewer ask next?
What does `yield` do?
It returns a value while suspending the generator, preserving its local state so execution can continue on the next iteration.
How do you iterate over a generator twice?
Create a new generator by calling its generator function again, or materialize the values if the result is small enough to store.
SAY IT OUT LOUD
How to explain this in an interview
“An iterable can create an iterator. The iterator tracks progress and returns values one at a time until it is exhausted. A generator is a convenient lazy iterator built with `yield` or a generator expression. It can reduce memory for large streams, but it is usually single-pass, so I would use a list when indexing or repeated traversal is needed.”
Connect this question to the roadmap topic it supports.