Skip to content

Colin Webb

Python Generators Cheatsheet

A quick cheatsheet showing Python's generators, covering usage of 'yield', behaviour on raising Exceptions, and Generator Expressions.

Basic yield

A generator function with two yields. Calling next results in successive yields.

Once exhausted, it returns StopIteration

>>> def simple_gen():
...     yield 1
...     yield 2
...
>>> g = simple_gen()
>>> g
<generator object simple_gen at 0x1011c0bf0>
>>> next(g)
1
>>> next(g)
2
>>> next(g)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Looping yield

An infinitely looping generator

>>> def looping_gen():
...     i = 1
...     while True:
...         yield i
...         i += 1
...
>>>
>>> g = looping_gen()
>>> next(g)
1
>>> next(g)
2
>>> next(g)
3

(and so on)

Closing a Generator

>>> g = looping_gen()
>>> g.close()
>>> g
<generator object looping_gen at 0x100f31000>
>>> next(g)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>

Raising Exceptions

A generator that raises an Exception is immediately stopped.

>>> def throwing_gen():
...     yield 1
...     raise Exception
...     yield 2
...
>>> g = throwing_gen()
>>> next(g)
1
>>> next(g)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in throwing_gen
Exception
>>> next(g)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Iterating a Generator

>>> g = simple_gen()
>>> for x in g:
...     print(x)
...
1
2

Or, convert to a list.

>>> g = simple_gen()
>>> list(g)
[1, 2]

Generator Expressions

List comprehensions are written with square brackets. Generator comprehensions are written with parentheses.

The difference; a generator is lazy list-comprehension.

>>> [x**2 for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> gen = (x**2 for x in range(1,11))
>>> gen
<generator object <genexpr> at 0x1036c2670>
>>> list(gen)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Chaining

>>> evens = (x for x in range(1,11) if x % 2 == 0)
>>> squared = (x**2 for x in evens)
>>> list(squared)
[4, 16, 36, 64, 100]

Further Reading (on Coroutines)

yield can also be used to create coroutines. I don't often use them, but there's an excellent in-depth talk/course available here: http://www.dabeaz.com/coroutines/