Python: assignment in lambdas

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 yin 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

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *