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
- What happen if you replace the
yield
s inspam
forreturn
s?, call iteggs
and run it twice consecutively. - 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>
- Would you write a generator for the Fibonacci Sequence?, something that behaves as follows: