I would like to use the following generator with a for
loop instead of a while
, exploiting the fact that for
implicitly calls next()
and handles StopIteration
on generators:
def gen():
failures = 0
ret = 0
while True:
yield ret
x = yield
ret += 1
if not x:
failures += 1
if failures == 20:
break
The main idea of this generator is sending a value and expecting a "feedbak" on the value. After 20 negative feedbacks, the generator terminates.
Now, I would expect this to be easily usable in a for
loop as follows:
g = gen()
for k in g:
print(k)
if k % 2:
g.send(False)
else:
g.send(True)
the idea being yield ret
is done every time the for
implicitly calls next()
and x = yield
is done every time g.send()
is called. Unfortunately, this does not work: in fact, for some reason, the generator always receives None
from the send.
The only way I managed to get this to work is changing the generator as follows:
def gen():
failures = 0
ret = 0
while True:
x = yield ret # this changes
ret += 1
if not x:
failures += 1
if failures == 20:
break
and using it like this:
g = gen()
k = g.send(None)
while True:
try:
print(k)
if k % 2:
k = g.send(False)
else:
k = g.send(True)
except StopIteration:
break
Is there any way to accomplish this using for
semantics to implicitly handle the generator's termination?