Sahaj.blogs
19 Oct 2023 · StudyPhase 1 · Python

Python · Generators

Generator functions with yield, lazy evaluation, infinite sequences, pipelines, and itertools.

A generator function is a function that contains yield. Calling it doesn’t run the body. Instead it returns a generator object, which is an iterator. Each next() runs the body up to the next yield, hands out that value, and pauses with its local state kept.

Why this is useful:

  • Lazy: values are produced only when someone asks for them, so memory stays small.
  • Infinite sequences are fine, as long as you take only what you need (itertools.islice).
  • Pipelines: chaining generators gives a stream-processing style.

The class iterator I wrote yesterday shrinks to a few lines as a generator.

from itertools import islice, count

def countdown(n):
    while n > 0:
        yield n
        n -= 1

print(list(countdown(5)))

def fib():
    a, b = 0, 1
    while True:          # infinite, but lazy
        yield a
        a, b = b, a + b

print(list(islice(fib(), 12)))

# pipeline: numbers -> squares -> only even -> first 5
squares = (n * n for n in count(1))
even_sq = (s for s in squares if s % 2 == 0)
print(list(islice(even_sq, 5)))

g = countdown(2)
print(next(g), next(g), next(g, "done"))

Output:

[5, 4, 3, 2, 1]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
[4, 16, 36, 64, 100]
2 1 done

#python#generators

Sources

  1. Generators (tutorial) — Python Software Foundation
  2. PEP 255: Simple Generators — Python Software Foundation
  3. itertools — Python Software Foundation