Troskyvs
Troskyvs

Reputation: 8077

python "send" method doesn't change the value of "next"?

I'm trying generator's send function, I was expecting that send will change the value that's being yield, so I tried in ipython:

In [17]: def z(n):
    ...:     i=0
    ...:     while(i<n):
    ...:         val=yield i
    ...:         print "value is:",val
    ...:         i+=1
    ...:
In [24]: z1=z(10)
In [25]: z1.next()
Out[25]: 0

In [26]: z1.send(5) # I was expecting that after "send", output value will become "5"
value is: 5
Out[26]: 1

In [27]: z1.next()
value is: None # I was expecting that z1.next() will restart from "6" because I sent "5"
Out[27]: 2

Well I suppose I had wrong understanding of what "send" really does, how to correct it?

Upvotes: 4

Views: 184

Answers (1)

niemmi
niemmi

Reputation: 17263

You're yielding i but you're not assigning the return value from yield statement to it. If you assign the return value you will see the output you expect:

def z(n):
    print 'Generator started'
    i=0
    while(i<n):
        val=yield i
        print "value is:",val
        if val is not None:
            i = val
        i+=1

z1=z(10)
print 'Before start'
print z1.next()
print z1.send(5)
print z1.next()

Output:

Before start
Generator started
0
value is: 5
6
value is: None
7

Update: When send or next is called for the first time the generator is executed from start to the first yield statement at which point value is returned to the caller. This is why value is: text is not seen on first call. When send or next is called for second time the execution resumes from yield. If send was called the parameter given to it is returned by the yield statement, otherwise yield returns None.

Upvotes: 6

Related Questions