Reverse Instructional Design --- Python Generators

Aug 13, 2014 • Francisco Palm

Sometimes you want functions that “save” its current state.

It is specially useful for implementing sequences like the famous Fibonacci Sequence.

In the Fibonacci sequence the next number is the sum of the two numbers before it. It starts with 0 and 1. i.e. 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …

For example, consider this generator:

def spam():
    print('hi')
    yield("first word")
    print('bye')
    yield("last word")

Note, that’s only a typical def function definition which uses yield instead of  return. Then you get:

>>> i = spam()
>>> i.next()
hi
'first word'
>>> i.next()
bye
'last word'

But, usually you use it in for loops:

>>> for i in spam():
...     print(i)
...
hi
first word
bye
last word

or list comprehensions:

>>> [i for i in spam()]
hi
bye
['first word', 'last word']

Questions

  1. What happen if you replace the yields in spam for returns?, call it eggs and run it twice consecutively.
  2. Can you write a generator named seq() that behave in this way?: (use a for loop that iterates over seq argument)
    >>> [ch for ch in seq("animalia")]
    ['a', 'n', 'i', 'm', 'a', 'l', 'i', 'a']

    And, what happen if you run [ch for ch in "animalia"]?</li>

    • Would you write a generator for the Fibonacci Sequence?, something that behaves as follows:
      >>> [i for i in fibonacci(100)]
      [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

      That gives a list with the Fibonacci numbers below 100.</li>

      • What about if you like the N first Fibonacci Numbers?</ol>