5 ms·
I'm not sure, why you think the value of the lambda function is thrown away. The lambda function returns a generator object. The function body of a generator is
by martin_k 15y ago
I'm not sure, why you think the value of the lambda function is thrown away. The lambda function returns a generator object. The function body of a generator is generally not executed until you call .next() on it, so that's why you don't get a NameError instantly. Also the value, that you .send() into the generator is not thrown away either. In your example the generator just runs into an exception before it goes into a state in which it would accept a .send() call. Just consider this modified example:
>>> f=lambda: (yield)
>>> gen=f()
>>> gen.next()
>>> gen.send('foobar')
'foobar'
- cool-RR 15y agoI think you misunderstood which value gets thrown away. Consider this: >>> g = lambda x: 7 >>> f = lambda: g((yield)) >>> list(f()) [None] Can you tell me where the 7 went to? As far as I see, it went into oblivion.
- martin_k 15y agoAs i said, f() returns a generator object in this case. So you're calling list on a generator that yields None once, the result of which is a list that contains None. If you change the `yield` to `yield "foobar"`, list(f()) will get you `["foobar"]`. Edit: Perhaps, to clear things up more, about where the value 7 went- your snippet can be expressed without using lambdas as >>> def g(x): ... return 7 ... >>> def f(): ... v = (yield) ... g(v) ... >>> list(f()) [None] Note that there's no return before g(v) because generators (at least in 2.7) can only yield, not return a value.
- pyre 15y agoI'm thinking that the parent is expecting 'yield' to return 'None' into g(), and then for g() to return 7 since it doesn't do anything with the 'x' parameter, and is confused why that isn't the case.
- martin_k 15y agoYes, but I think this is cleared up if you consider that calling a generator function does not execute its body, but return generator object. It doesn't really matter if it's a lambda or a regular named function.
- cool-RR 15y agoSure, I understand all of that. I'm just saying it's unusual to see a lambda function throwing away the value like that.
- martin_k 15y agoThe value of the lambda is the generator object. How else could you call list() on it if it was thrown away?
- cool-RR 15y agoYou're just using the word "value" in a different way. I meant "value" as in the 7.
- martin_k 15y agoYou're right. I am still referring to that particular part of your blog post: >> So that’s the only case I can think of where Python >> completely throws away the value of a lambda function.
- ul5255 15y agoStrange. With Python 2.6 I get [None, 7] while with Python 2.7 it is [None]. Looking at the OP codes the 2.7 one's look weird. Python 2.6: >>> dis.dis(f) 1 0 LOAD_GLOBAL 0 (g) 3 LOAD_CONST 0 (None) 6 YIELD_VALUE 7 CALL_FUNCTION 1 10 RETURN_VALUE Python 2.7: >>> dis.dis(f) 1 0 LOAD_GLOBAL 0 (g) 3 LOAD_CONST 0 (None) 6 YIELD_VALUE 7 CALL_FUNCTION 1 10 POP_TOP 11 LOAD_CONST 0 (None) 14 RETURN_VALUE In essence the Python 2.7 compiler decides to throw away the result of the g() function call and replaces it with None. Does anyone understand why?