top-level names1def countdown(n):2 while n > 0:3 yield n4 n -= 15gen = countdown(3)6print(next(gen))7print(next(gen))8for x in gen:9 print(x)generator: countdown(3)StopIterationcountdown(3)next(gen)3next(gen)2next(gen)1
Code card: countdown.py; the highlighted lines are the ones runningFront tray: the generator, its local n, the line it runs next and its stateBack tray: the top-level names gen and xTerminal: where print() writesAn iterator hands out one value per next() call and raises StopIteration when it has no more; a for loop calls next() for you. A generator is an iterator written as a function with yield. Each step lights the parts it is about: a next(gen) token hops from the calling line into the generator (the front tray), its local n and next line crossfade as the body runs, and each yielded value hops out to the terminal or into x. Between calls the generator is paused, keeping n and its place. When n reaches 0 it raises StopIteration, the for loop ends quietly and the generator's frame is gone.

Iterators

  1. An iterator hands out values one at a time. Each next() call returns the next value; when none are left, it raises StopIteration. A for loop is built on this: it calls next() for you until StopIteration.

Inside a generator

The end

Try it yourself

;; step 1/9
>>> it = iter([10, 20])   # a list gives an iterator
>>> next(it)
10
>>> next(it)
20
>>> next(it)
Traceback (most recent call last):
  ...
StopIteration

The "next line" box is a picture of what Python keeps for a paused generator: its local variables and where in the body to carry on. While a generator is suspended, gen.gi_frame.f_lineno reports the yield line itself (line 3); it carries on with the line after it. A generator runs only once. When it is finished, every further next() raises StopIteration at once, and a for loop over it does nothing. Call countdown(3) again to get a fresh one.