๐ŸŒŠGenerators: yield, yield from, send()LESSON

Generators: yield, yield from, send()

Generators are one of Python's most elegant features. They let you write iterators with ordinary function syntax, produce values lazily (on demand), and compose powerful data pipelines โ€” all while using dramatically less memory than building full lists.

Generator Functions and yield

A generator function looks like a regular function but uses yield instead of return. When called, it doesn't execute immediately โ€” it returns a generator object (which is an iterator):

Execution is suspended at each yield. The function's local state (variables, position in the code) is preserved between calls to next().

Generator Objects Are Iterators

Generator objects implement both __iter__ and __next__, so they work everywhere iterators work:

Lazy Evaluation โ€” Values on Demand

The key advantage: a generator only computes the next value when you ask for it. This is called lazy evaluation:

Memory Comparison: list vs generator

For large sequences, generators use O(1) memory while lists use O(n):

Generator Expressions

Just as list comprehensions have a concise syntax, generators do too โ€” use parentheses instead of brackets:

Generator State: Lifecycle

A generator moves through distinct states:

yield from โ€” Delegating to Sub-generators

yield from iterable delegates to another iterable, yielding all its values:

yield from also properly handles send() and throw() calls by forwarding them to the sub-generator.

send() โ€” Passing Values Into a Generator

Generators are not just one-way pipes. You can send values back in with gen.send(value). The yield expression receives the sent value:

Important: You must call next(gen) (or gen.send(None)) first to advance to the first yield before you can send() a non-None value.

Practical Uses

Infinite sequences without memory cost:

Data pipelines โ€” chain transformations lazily:

Knowledge Check

What does a generator function return when called?

When is the body of a generator function first executed?

What is the purpose of `yield from subgenerator`?