TL;DR Use default parameters to simulate assignment in lambdas.
Unlike C and C++, in Python assignment is an expression, not a statement. Python lambda can only return an expression, which means that there is no way to assign values for future reuse.
E.g., if we want to calculate (x2 + 2x + 7) + sqrt(x2 + 2x + 7), we can write a regular function as follows:
from math import sqrt def mymath(x): y = x**2 + 2*x + 7 return y + sqrt(y)
However, when defining a lambda, we cannot simply assign a variable like this:
from math import sqrt # SyntaxError: invalid syntax mymath = lambda x: (y = x**2 + 2*x + 7; y + sqrt(y))
Fortunately, there is a way to beat the system:
from math import sqrt mymath = lambda x: (lambda y: y + sqrt(y))(x**2 + 2*x + 7)
Here the outer lambda creates an inner lambda, and then immediately executes it, supplying x**2 + 2*x + 7
as a parameter. It is bound to y
in the inner lambda and is calculated only once. This works, but the order of calculations is counterintuitive: we first evaluate the expression on the right, and then the expression on the left. We can do better with default parameter values:
from math import sqrt mymath = lambda x: (lambda y = x**2 + 2*x + 7: y + sqrt(y))()
Here we create an inner lambda where parameter y
has default value of x**2+2*x+7
, and then immediately execute it supplying no arguments. y
takes the default value and is calculated only once. We can even create multiple variables this way, as long as they are independent:
from math import sqrt mymath = lambda x: (lambda y = x**2 + 2*x + 7, z = x**3 + 12: y - z + sqrt(y + z))()
This looks almost like a regular function with assignments, but it’s still a lambda.
Credit: https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
Permalink
Function composition?
Permalink
Yep