Why did this Python generator / coprocessor lose value?

While reading about Python coroutines, I came across this code:

def countdown(n): print("Start from {}".format(n)) while n >= 0: print("Yielding {}".format(n)) newv = yield n if newv is not None: n = newv else: n -= 1 c = countdown(5) for n in c: print(n) if n == 5: c.send(2) 

which curiously deduces:

 Start from 5 Yielding 5 5 Yielding 3 Yielding 2 2 Yielding 1 1 Yielding 0 0 

In particular, it skips printing 3 . Why?


This question does not answer this question because I am not asking what send does. It returns the values ​​back to the function. I ask why, after the release of send(3) , the next result, which should give 3, does not cause the for 3 loop to print.

+5
source share
2 answers

You never checked the return value of your c.send(3) call. In fact, it turns out that the send method itself promotes the generator, so your missing 3 was yield ed in this c.send(3) call.

 def countdown(n): while n >= 0: newv = yield n if newv is not None: n = newv else: n -= 1 c = countdown(5) print(next(c)) print(c.send(3)) print(next(c)) 

The conclusion will be:

 5 3 2 

Actually documented :

generator.send (value)

Resumes execution and "sends" the value to the generator function. The value argument is the result of the current yield expression. The send () method returns the next value received by the generator, or returns StopIteration if the generator exits without giving way to another value.

+4
source

You fail in c.send() . You compare when n == 5, but you do not send 5 (in your function n-1), you send 3. For example, it does not print 4.

Try using the same code, but with c.send(5) it will print from 5 to 0.

 c = countdown(5) for n in c: print(n) if n == 5: c.send(5) 
0
source

Source: https://habr.com/ru/post/1269961/


All Articles