Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the yield expression collapse?

Tags:

python

yield

I was messing around and noticed that the following code yields the value once, while I was expecting it to return a generator object.

def f():
    yield (yield 1) 
f().next() # returns 1

def g():
    yield (yield (yield 1) 
g().next() # returns 1

My question is what is the value of the yield expression and also why are we allowed to nest yield expression if the yield expression collapses?

like image 433
Durwasa Chakraborty Avatar asked Sep 09 '18 18:09

Durwasa Chakraborty


People also ask

What does it mean when the yield goes down?

A bond can be purchased for more than its face value, at a premium, or less than its face value, at a discount. The current yield is the bond's coupon rate divided by its market price. Price and yield are inversely related and as the price of a bond goes up, its yield goes down.

What causes the yield curve to flatten?

A steepening curve typically signals expectations of stronger economic activity, higher inflation, and higher interest rates. A flattening curve can mean the opposite: investors expect rate hikes in the near term and have lost confidence in the economy's growth outlook.

Why does yield curve slope downwards?

An inverted yield curve, which slopes downward, occurs when long-term interest rates fall below short-term interest rates. In that unusual situation, long-term investors are willing to settle for lower yields, possibly because they believe the economic outlook is bleak (as in the case of an imminent recession).

What happens when yield curve shifts down?

An inverted yield curve instead slopes downward and means that short-term interest rates exceed long-term rates. Such a yield curve corresponds to periods of economic recession, where investors expect yields on longer-maturity bonds to become even lower in the future.


1 Answers

The value of the yield expression after resuming depends on the method which resumed the execution. If __next__() is used (typically via either a for or the next() builtin) then the result is None. Otherwise, if send() is used, then the result will be the value passed in to that method.

So this:

def f():
    yield (yield 1) 

Is equivalent to this:

def f():
    x = yield 1
    yield x

Which in this case (since you're not using generator.send()) is equivalent to this:

def f():
    yield 1
    yield None

Your code is only looking at the first item yielded by the generator. If you instead call list() to consume the whole sequence, you'll see what I describe:

def f():
    yield (yield 1)

def g():
    yield (yield (yield 1)) 


print(list(f()))
print(list(g()))

Output:

$ python3 yield.py 
[1, None]
[1, None, None]

If we iterate the generator manually (as you have), but .send() it values, then you can see that yield "returns" this value:

gen = f()
print(next(gen))
print(gen.send(42))

Output:

$ python3 yield_manual.py 
1
42
like image 144
Jonathon Reinhart Avatar answered Sep 20 '22 01:09

Jonathon Reinhart