Reputation: 47
I was trying python's generators (together with from) but endup with infinite loop. My python version is python3. why did I stuck into infinite loop?
Below is my code:
def fib2():
a,b = 0,1
while True:
yield a
a,b = b , a+b
def FibNumber(num):
fi2= fib2()
for i in range(num):
yield from fi2
if (__name__ == "__main__"):
fin = FibNumber(10)
for i in fin:
print (i)
Upvotes: 0
Views: 95
Reputation: 101
Use the next value of your fib2 generator for every sequence of loops.
def fib2(n):
a,b = 0,1
i = 0
while i <=n:
yield a
a,b = b , a+b
def FibNumber(num):
fi2= fib2()
for i in range(num):
yield next(fi2)
if (__name__ == "__main__"):
fin = FibNumber(10)
for i in fin:
print (i)
Upvotes: 0
Reputation: 1
I think you have to force a break in your for loop.
def fib2():
a,b = 0,1
while True:
yield a
a,b = b , a+b
def FibNumber(num):
fi2= fib2()
a = 0
for i in fi2:
a += 1
if a > num:
break
yield i
if (__name__ == "__main__"):
fin = FibNumber(10)
for i in fin:
print (i)
Upvotes: 0
Reputation: 752
Just replace FibNumber(num)
with the following:
def FibNumber(num):
fi2= fib2()
yield from (next(fi2) for i in range(num))
Upvotes: 0
Reputation: 36735
This is due to fact that you used yield from
with infinite generator. PEP 380 says that:
yield from <expr>
where <expr>
is an expression evaluating to an iterable, from which an iterator is extracted. The iterator is run to exhaustion, during which time it yields and receives values directly to or from the caller of the generator containing the yield from expression (the "delegating generator").
(bold by me)
Upvotes: 2
Reputation: 532268
fin
is indeed an infinite generator. FiBNumber
doesn't do what you intended; for each value of i
, it tries to yield everything from fi2
. A more correct definition would be
def FibNumber(num):
fi2 = fib2()
for i in range(num):
yield next(fi2)
However, you are really just reimplementing itertools.islice
:
from itertools import islice
for i in islice(fib2(), 10):
print(i)
Upvotes: 2
Reputation: 6298
You can use the __next__() in the second iterator.
def FibNumber(num):
fi2= fib2()
for i in range(num):
yield fi2.__next__()
Upvotes: 0