GGistDev

Generators in Python

Generators are functions that yield values one at a time, enabling lazy, memory‑efficient iteration.

yield and basic generators

Use yield to produce a sequence lazily.

def count(n):
    i = 0
    while i < n:
        yield i
        i += 1

Consume with for or next().

for i in count(3):
    print(i)

Generator expressions

Lightweight syntax for inline generators.

total = sum(n*n for n in range(10))

send, throw, and close (advanced)

Generators can receive values and exceptions.

def accumulator():
    total = 0
    while True:
        x = (yield total)
        if x is None: break
        total += x

Pipelines and composition

Chain generators to build streaming pipelines.

def read_lines(path):
    with open(path, encoding="utf-8") as f:
        for line in f:
            yield line.rstrip("\n")

def grep(pattern, lines):
    for line in lines:
        if pattern in line:
            yield line

for line in grep("ERROR", read_lines("app.log")):
    print(line)

itertools

The itertools module provides building blocks for efficient iteration (e.g., chain, islice, takewhile).

Best practices

  • Prefer generators when results are consumed once or may be large
  • Keep generator state simple; avoid global mutable state
  • Handle cleanup by using with inside generators that access resources

Summary

  • yield creates lazy iterators; generator expressions are concise
  • Compose pipelines for efficiency and clarity; use itertools helpers