Reputation: 3455
Just found out about the yield from
construct, which to my idea is somewhat like a reversed yield
, instead of getting an object out of a generator, you insert/ send an object to a generator. Like:
def foo():
while True:
x = (yield)
print(f'{x=}')
f = foo()
f.send(None)
for i in range(4):
f.send(i)
yields:
x=0
x=1
x=2
x=3
So then I wondered if you can combine the two.
def foo():
while True:
x = (yield)
print(f'{x=}')
yield x + 1000
f = foo()
f.send(None)
for i in range(4):
print(f'y={f.send(i)}')
Then I would expect
x=0
y=1000
x=1
y=1001
x=2
y=1002
x=3
y=1003
but I get
x=0
y=1000
y=None
x=2
y=1002
y=None
Anyone can explain this?
Upvotes: 2
Views: 241
Reputation: 44444
If you'd 'combine the two', it's useful to think of yield
as a single point of sending values out, and then accepting values in from outside. That way, you might appreciate why you don't get a line printing out "x=" every alternate line and get None
s every third line in your output. This is because the control comes out of foo(..)
two times every loop in the while
block.
Here's the fixed version of your code:
def foo():
x = 0
while True:
x = (yield x + 1000)
print(f'{x=}')
f = foo()
f.send(None)
for i in range(4):
print(f'y={f.send(i)}')
Upvotes: 3