Difference between Python's Generators and Iterators
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Generators and iterators are closely related in Python, but they are not the same concept. An iterator is any object that follows the iterator protocol, while a generator is a specific, convenient way to create an iterator, usually by writing a function with yield.
What an Iterator Is
An iterator is an object that can produce one item at a time. In Python terms, an iterator must support:
- '
__iter__(), which returns the iterator object itself' - '
__next__(), which returns the next item or raisesStopIteration'
A custom iterator class can look like this:
This is an iterator because it implements the protocol directly.
What a Generator Is
A generator is an iterator created by a generator function or generator expression. Instead of writing __next__() manually, you use yield.
This generator function produces an iterator automatically. Python handles the iterator machinery for you.
The Relationship Between Them
The key relationship is:
- every generator is an iterator
- not every iterator is a generator
That is the conceptual difference. A generator is a special case of iterator with more convenient syntax and automatic state management.
Why Generators Feel Easier
Generators are often simpler because you do not need to build a class just to maintain iteration state. Local variables inside the generator function are preserved automatically between yield points.
This makes generators especially good for:
- streaming data
- lazy transformations
- pipeline-style processing
- reading large files incrementally
They express "produce values over time" very naturally.
Iterators Give You More Control
Custom iterator classes still matter when you need more explicit control over state, methods, or object behavior. For example, an iterator class can expose extra configuration or integrate more naturally with a larger object model.
So generators are more convenient in many cases, but iterators are the broader mechanism underneath.
Memory and Laziness
Both generators and iterators can be lazy, meaning they produce values one at a time instead of creating a full list in memory. This is one reason they are useful for large or infinite sequences.
For example:
That sequence can continue indefinitely because values are generated on demand.
Common Pitfalls
Thinking generators and iterators are unrelated concepts misses the fact that generators are one concrete way to implement iteration.
Assuming every iterable object is already an iterator is incorrect. Lists are iterable, but calling next() on a list directly fails until you wrap it with iter().
Using a generator once and then expecting it to restart automatically is a common mistake because generators are single-pass iterators.
Choosing a custom iterator class when a simple generator function would do can add unnecessary boilerplate.
Assuming laziness belongs only to generators is too narrow because iterators in general can be lazy too.
Summary
- An iterator is any object that implements the iterator protocol.
- A generator is a convenient way to create an iterator, usually with
yield. - Every generator is an iterator, but not every iterator is a generator.
- Generators are often simpler for streaming or lazy data production.
- Custom iterator classes are still useful when you need more explicit state or object behavior.

