Learn with diagrams, code, systems and practical examples.
Iterators and Generators
Process values lazily instead of building every result at once.
Lazy iteration can reduce memory use and make streaming workflows natural.
Start with the idea
An iterator produces one value at a time. A generator function uses yield to produce a sequence lazily while preserving its execution state between values.
Small working example
Run this example first. Do not change several things at once; confirm the basic behavior, then experiment.
def countdown(start):
current = start
while current > 0:
yield current
current -= 1
print(list(countdown(3))) An iterator produces one value at a time. A generator function uses yield to produce a sequence lazily while preserving its execution state between values.
- Iterators produce values sequentially.
- Generators make iterators easy to write.
- Lazy evaluation can save memory.
[3, 2, 1]The example is intentionally small. Focus on the chapter’s main idea before adding extra syntax or framework code.
Common beginner mistake
Converting a generator to a list immediately when the whole point was to avoid materializing everything.
Keep values lazy when downstream code can consume them one at a time.
Quick recap
- Iterators produce values sequentially.
- Generators make iterators easy to write.
- Lazy evaluation can save memory.
Try it yourself
These are deliberately small. If you can complete them without copying the example, you are ready to continue.
- Write a generator for even numbers.
- Consume it with a for loop instead of list().