Reputation: 5159
I'm learning python via learnpython.org. I made it through all of the basic classes just fine, but I'm having trouble with the Generators level.
I think I understand how the yield
command works, but I can't figure out how to use it to get the Fibonacci sequence I need to complete the lesson. Here's my code, but it only gives me the first 2 numbers.
# fill in this function
def fib():
a,b = 1,0 # Sets the values (is this causing a problem?)
yield a # Sends back the value of a to the iterator (for loop)
b = a + b # Sets the value of b to a + b
yield b # Sends back the value of b to the iterator (for loop)
# testing code
import types
if type(fib()) == types.GeneratorType:
print "Good, The fib function is a generator."
counter = 0
for n in fib():
print n
counter += 1
if counter == 10:
break
This is most annoying, as I would like to complete this level, but I don't know how.
Upvotes: 1
Views: 106
Reputation: 168626
Your generator will produce one result for each yield
statement executed. You only executed two yield
statements, so your generator produced two results.
Try this:
def fib():
a,b = 1,0 # Sets the values (is this causing a problem?)
while True:
a,b = b, a + b # Sets the value of b to a + b
yield b # Sends back the value of b to the iterator (for loop)
As you can see, the while
loop will run forever, so this generator will produce an indefinite (infinite?) number of results.
Alternatively, you can modify your generator to produce a finite sequence, and modify your caller to take advantage of that:
def fib(counter=None, limit=None):
a,b = 0,1
i = 0
while (counter is None or counter > i) and (limit is None or limit > b):
i += 1
yield b
a,b = b, a + b
print list(fib(counter=10))
print list(fib(limit=60))
Upvotes: 4
Reputation: 1597
In python, there is always an implicit return
at the end of each function. So when your generator reaches the end of the function, after the second yield, it halts. If you want to keep going (an infinite generator) you need to put the yields in an infinite loop.
def fib():
current, past = 1, 0
while True:
yield current
current, past = current + past, current
Side note:
Also, python has a nice function for grabbing the first N items from an infinite generator built in to a cool library called itertools, so the second part could be cleaned up like this:
from itertools import islice
for number in islice(fib(), 10):
print(number)
Upvotes: 0