Iterators & Generators
Produce values one at a time, lazily, with yield.
Syntax
def gen():
yield valueAn iterator produces items one at a time. A generator is the easiest way to make one: write a function that uses yield instead of return.
Why generators?
They are lazy — values are produced only as needed, so you can work with huge or even infinite sequences without storing them all in memory.
Example
Loading editor…
Press Run to execute the code.
When to use it
- A log reader uses a generator to stream lines from a multi-gigabyte file without loading it all into memory.
- A data pipeline yields transformed records one at a time so memory stays constant regardless of dataset size.
- An infinite counter generator produces unique IDs on demand without pre-generating a list.
More examples
Simple generator function
Defines a generator that yields values one at a time instead of returning a list.
def countdown(n):
while n > 0:
yield n
n -= 1
for val in countdown(5):
print(val, end=' ')
# Output: 5 4 3 2 1Generator for large file reading
Yields lines from a file one by one, keeping memory usage constant for arbitrarily large files.
def read_lines(filepath):
with open(filepath) as f:
for line in f:
yield line.rstrip()
for line in read_lines('notes.txt'):
print(line)Generator expression
Creates a lazy generator expression (like a list comprehension with parentheses) that computes values on demand.
numbers = range(1, 1_000_001)
squares_gen = (n ** 2 for n in numbers if n % 2 == 0)
print(next(squares_gen)) # 4
print(next(squares_gen)) # 16
print(sum(squares_gen)) # rest of the evens squared
Discussion