Site Tools


python-generators

Python generators

Python generators are functions that use yield to produce a sequence of values lazily, one at a time. Instead of computing all values and returning a list, generators suspend execution at each yield, resuming when the next value is requested. They're memory-efficient for large sequences and enable elegant state machines.

Use generators for processing large datasets, infinite sequences, or building pipelines where intermediate results don't need to exist simultaneously.

Example

This example shows generators for lazy evaluation and state machines.

# run: python3 generators.py
# description: generators for lazy sequences and state machines
 
# Simple generator
def count_up_to(n):
    i = 0
    while i < n:
        yield i
        i += 1
 
print("Counting:")
for num in count_up_to(5):
    print(f"  {num}")
 
# Generator as pipeline
def squares(numbers):
    for n in numbers:
        yield n * n
 
def evens_only(numbers):
    for n in numbers:
        if n % 2 == 0:
            yield n
 
# Compose generators
numbers = range(10)
result = list(evens_only(squares(numbers)))
print(f"\nEven squares: {result}")
 
# Generator state machine
def reader(filename):
    with open(filename, 'w') as f:
        f.write("line1\nline2\nline3\n")
 
    with open(filename) as f:
        for line in f:
            yield line.strip()
 
import tempfile
import os
with tempfile.TemporaryDirectory() as tmpdir:
    filepath = os.path.join(tmpdir, "test.txt")
    print("\nReading file:")
    for line in reader(filepath):
        print(f"  {line}")
 
# Generator expression (like list comprehension but lazy)
gen = (x * 2 for x in range(1000000))
print(f"\nGenerator type: {type(gen)}")
print(f"First few: {[next(gen) for _ in range(3)]}")
 
# Infinite generator
def infinite_sequence(start=0):
    n = start
    while True:
        yield n
        n += 1
 
gen = infinite_sequence(100)
print(f"Infinite: {[next(gen) for _ in range(5)]}")

Common patterns

Generator functions:

  • def func(): yield value: function that returns a generator object
  • Each yield suspends the function; next next() resumes it
  • return value (Python 3.3+) returns value from StopIteration exception

Generator expressions:

  • (x for x in iterable): like list comprehension but lazy
  • Syntax: same as list comp but parentheses instead of brackets
  • More memory-efficient; compute on demand

Lazy evaluation:

  • Values computed only when requested
  • Can represent infinite sequences
  • Chains efficiently: generator of generators

Pipeline composition:

  • Combine generators for data processing
  • Each stage produces values on demand
  • No intermediate lists allocated

Generator methods:

  • next(gen): get next value; raises StopIteration when done
  • gen.send(value): resume with value; rarely used
  • gen.throw(exception): throw exception into generator
  • gen.close(): stop generator

Bidirectional communication:

  • value = (yield received_value): receive and send values
  • Advanced pattern for coroutines (use async/await instead)

Common uses:

  • Reading large files line-by-line
  • Processing infinite streams
  • Building data pipelines
  • Implementing state machines
  • Fibonacci, primes, other sequences

Comparison with list comprehension:

  • List: [f(x) for x in range(1000000)]: creates million-item list immediately
  • Generator: (f(x) for x in range(1000000)): computes on demand, constant memory
python-generators.md · Last modified: by 127.0.0.1