Python for Developers

First Edition

Chapter 15: Generators


Functions generally follow the conventional process flow, return values and quit. Generators work similarly, but remember the state of the processing between calls, staying in memory and returning the next item expected when activated.

Generators have several advantages over conventional functions:

  • Lazy Evaluation: generators are only processed when it is really needed, saving processing resources.
  • They reduce the need to create lists.
  • They allow working with unlimited sequences of elements.

Generators are usually called through a for loop. The syntax is similar to the traditional function, but with the yield instruction substituting for return. In each new iteraction, yield returns the next value.

Exemplo:

In [4]:
def gen_pares():
    """
    Generates even numbers from 0 to 20
    """
    i = 0

    while i <= 20:
        yield i
        i += 2

# Shows each number and goes to the next
for n in gen_pares():
    print n
0
2
4
6
8
10
12
14
16
18
20

Another example:

In [2]:
import os

# Finds files recursively
def find(path='.'):

    for item in os.listdir(path):
        fn = os.path.normpath(os.path.join(path, item))

        if os.path.isdir(fn):

            for f in find(fn):
                yield f

        else:
            yield fn

# At each interaction, the generator yeld a new file name
for fn in find():
    print fn
.ipynb_checkpoints/Chapter15_Generators-checkpoint.ipynb
Chapter15_Generators.ipynb

There are many generators that are built in to the lanaguage, like xrange(). Moreover, in the module itertools, many useful generators are defined.

To convert the output of a generator into a list:

alist = list(generator())

That way, all the items will be generated at once.

In [1]:
 
Out[1]: