Python: two "yield"s in one function

3.7k views Asked by At

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?

2

There are 2 answers

0
vaultah On BEST ANSWER

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
0
llogiq On

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.