1.3.9 · D3Python Intermediate

Worked examples — Generators — yield, generator functions, send(), next()

2,602 words12 min readBack to topic

The scenario matrix

Before any code, let's list every distinct behaviour a generator can show. Think of each row as a trap the language can spring on you. Every worked example below is tagged with the cell it hits, so by the end you'll have touched all of them.

# Case class The specific edge Example that covers it
A Empty output generator that yields zero times Ex 1
B Exactly one value one yield, then StopIteration Ex 1
C Finite many normal loop, ends cleanly Ex 2
D Infinite / lazy while True, never ends by itself Ex 3
E Single-use exhaustion looping the same generator twice Ex 4
F send() before priming the TypeError trap Ex 5
G send() after priming value flows in and out Ex 5
H return inside a generator value hidden in StopIteration.value Ex 6
I Delegation yield from forwarding + capturing the sub-return Ex 7
J Real-world word problem streaming a huge file, memory win Ex 8
K Exam-style twist ordering of side-effects (when does code run?) Ex 9

Related vault ideas we'll lean on: Iterators and the Iterator Protocol, Lazy Evaluation, StopIteration and Exceptions, Coroutines and async, Memory and Big Data Streaming, and the contrast in List Comprehensions vs Generator Expressions.


Example 1 — Empty and one-value cases (cells A & B)


Example 2 — Finite many, counted (cell C)


Example 3 — Infinite / lazy, take only what you need (cell D)

Here's the picture of why an infinite generator doesn't hang: values are produced one at a time, on demand, never all at once.

Figure — Generators — yield, generator functions, send(), next()

Example 4 — Single-use exhaustion (cell E)


Example 5 — send(): before vs after priming (cells F & G)

This is the two-way street: the picture shows a value flowing out at yield, and a value flowing in as the result of that same yield expression.

Figure — Generators — yield, generator functions, send(), next()

Example 6 — return inside a generator (cell H)


Example 7 — yield from delegation (cell I)


Example 8 — Real-world: streaming a huge log, memory win (cell J)

The whole point: a generator holds one line at a time, not the whole file. The figure contrasts a list (all rows in memory) with a generator (a single moving window).

Figure — Generators — yield, generator functions, send(), next()

Example 9 — Exam twist: WHEN does the code run? (cell K)


80/20 — the scenarios that catch people

Recall Self-test

A generator yields 3 values then return "z". What does list(g) give? ::: [v1, v2, v3] — the "z" is discarded by list. g.send(5) on a brand-new (unprimed) generator does what? ::: raises TypeError. How many lines of a 10M-line file are in memory when streamed by a generator pipeline? ::: essentially one at a time. After list(g) exhausts g, what is list(g) the second time? ::: [] — generators are single-use.