**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 (x^{2} + 2x + 7) + sqrt(x^{2} + 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