Reputation: 319
We find an interesting issue on yield
of Python. We wrote a simple program:
def F():
for i in range(5, 9):
for j in range(21, 29):
x = yield i
y = (yield j) * 100
x += y
print '>>>', x
gen = F()
next(gen)
a1 = gen.send(66)
a2 = gen.send(77)
print a1
print a2
The result is amazing:
>>> 7766
21
5
i=5, j=21 => yield i => a1=21 => send(66) => x = 66
i=5, j=21 => yield j => a2=5 => send(77) => y = 7700
print 7766
print 21
print 5
i.e. after yield i
, a1
gets the value of j
; after yield j
, a2
gets the value of i
.
Does anyone know why yield
do like this? Why not a1=5, a2=21?
Upvotes: 1
Views: 3757
Reputation: 46533
next(gen)
takes the first element from the generator (i
):
next(gen) # 5
Then gen.send(66)
is equal to j
(which is 21). Since your second loop is still working, subsequent gen.send(77)
is equal to i
(which is still 5).
Essentially, the problem is that you consume 3 values, instead of 2.
Use gen.send(None)
or next(gen)
to start the generator:
a1 = gen.send(None) # or a1 = next(gen)
a2 = gen.send(77)
print(a1, a2) # prints 5 21
Upvotes: 3
Reputation: 14511
next(gen)
calls into the method, which returns from the first yield i
. Your a1 = gen.send(66)
then resumes the method at y = (yield j) * 100
and yields j
from there. The a2 = gen.send(77)
line resumes the method directly afterwards and returns from x = yield i
.
Upvotes: 1