Python Generators

Generators is a powerful weapon of Python. Generators help you write concise code, give you lazy evaluation, and improve the efficience for calculating large sets of results. Personally I think it’s a good habit to use generators in Python whenever you can, if you really want your code to be Pythonic.

How to create a generator

There are mainly two ways to create a generator: using the yield keyword in the function, or using the () as a generator expression.

• The yield keyword makes the function yields control back to the calling function on every iteration
• The () expression returns a generator object

How to refactor a function to use a generator

Functions that construct a list or another iterable and returns it can be turned into a generator by:

1. Converting the list append into a yield
2. Removing the empty list creation
3. Removing the return

A generator example

Let’s see an example: implement a function that takes a list and return a list of the current running mean. For example, given the input list [8, 4, 3, 1, 3, 5], the expected return result is [8.0, 6.0, 5.0, 4.0, 3.8, 4.0].

First we’ll implement it without using generators.

Now we can refactor the above implementation to use a generator:

What we did in the refactoring was: replacing the list appending with a yield (average.append()), removing the empty list creation (average = []), and replacing the return statement with a yield statement.

One important property of Python generator object is it is a single-use object. In other words, a generator keeps yielding answers forever. The looping in a generator only ends when the calling function decides to end it. Meanwhile a generator can only be called once.

A few other generator examples can be found on my GitHub repo IntermediatePython