21 def power(values):
22 print "power", values
23 for value in values:
24 print 'powering %s' % value
25 yield value
26
27 def adder(values):
28 print "adder", values
29 for value in values:
30 print 'adding to %s' % value
31 if value % 2 ==0:
32 yield value + 3
33 else:
34 yield value + 2
35
36 elements = [1, 4, 7, 9, 12, 19]
37 res = adder(power(elements))
38 print res.next()
39 print res.next()
40 print res.next()
41 print res.next()
OUTPUT:
adder <generator object power at 0x7fb6b9ee7910> <--- is this the stdout flush matter?
power [1, 4, 7, 9, 12, 19]
powering 1
adding to 1
3
powering 4
adding to 4
7
powering 7
adding to 7
9
powering 9
adding to 9
11
I am trying to understand the above code.
1) why did adder got printed before power [1, 4, 7, 9, 12, 19]?
2) adder is not iterating through elements but iterating through power generator, correct?
3) confirm my thought on (1). so adder gets called first then in for value in values for adder, it's consulting power generator and hence, powering print line gets triggered and then adder print line gets triggered?
4) If so, why doesnt the print statement power [1, 4, 7, 9, 12, 19] gets called along with the powering <$> print statement every time?
power has a yield return, which makes it a generator. The code in the function itself is only execute when next() is called on it.adder relies on the generator, and has no information on the data being iterated. (such as the size)yield is a particular instruction. It does not return from the generator function (power). Instead, it provides one value, and suspend its execution until the next call to next(). At this point, the execution is resumed at the same point, which is inside the loop.Illustration of the yield stopping point:
def gene():
print 'first!'
yield 1
print 'second!'
yield 2
g = gene()
g.next()
# first!
# 1
g.next()
# second!
# 2
As you can see, the generator is interrupted exactly after the yield instruction, ready to execute the next one
Generator functions don't begin execution until the first call to __next__ on the generator. For example:
>>> def gen():
... print 'starting execution'
... for i in range(10): yield i
...
>>> itr = gen()
>>> next(itr)
starting execution
0
So to answer you first question, "why did adder got printed before power", when you do adder(power(elements)) the generator power(elements) is created first, but the execution of that generator will not begin until the first iteration of for value in values within adder().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With