python: lambda, yield-statement/expression and loops (Clarify)
Is it any necessity for using yield
inside of lambda
if you can rewrite it with generator such that?
In[1]: x = (i for i in range(15))
In[2]: x
Out[2]: <generator object <genexpr> at 0x7fbdc69c3f10>
In[3]: print(*x)
Out[3]: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
In[4]: x = (i for i in range(0, 15))
In[5]: x.__next__()
Out[5]: 0
In[6]: next(x)
Out[6]: 1
The one-liner you seem to be trying to create is actually technically possible with a lambda, you just need to help the parser a bit more:
>>> lamyield = lambda: [(yield x) for x in range(15)]
>>> print(*lamyield())
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
This uses a for loop implicitly in a list comprehension. It is not possible with an explicit while
loop or for
loop outside of a comprehension. That's because lambdas in python can only contain expressions, and to write an explicit loop you will need to use statements.
Note: this syntax is deprecated in Python 3.7, and will raise SyntaxError
in Python 3.8
You actually can loop through a lambda in useful ways, it's just that the example you provided isn't a great use case.
One instance where you might want to use yield
inside a lambda
might be to lazily execute expensive functions only when needed. Like so:
def expensive_check1():
print("expensive_check1")
return True
def expensive_check2():
print("expensive_check2")
return True
def expensive_check3():
print("expensive_check3")
return True
def do_the_thing(*args):
print(args)
if __name__=="__main__":
for check, args in (lambda: (
(yield (expensive_check1(), ["foo", "bar"])),
(yield (expensive_check2(), ["baz"])),
(yield (expensive_check3(), [])),
))():
if check:
do_the_thing(*args)
continue
raise Exception("oh noes!!!")
else:
print("all OK!")
Output:
expensive_check1
('foo', 'bar')
expensive_check2
('baz',)
expensive_check3
()
all OK!
Note that the expensive checks only happen at the start of each loop, rather than all at once. Also note that this syntax will still work in Python 3.8+, since it is not using the yield
inside of a comprehension.