# On Python's lambda and closures

### 25 Jul 2017

• Today, my friend Laurent was grumping about the “crappy” scipy.optimize.minimize function that did not respect the constraints he provided with lambda functions. This is how I re-discovered the consequences of one of the funniest features in Python: the closures of lambda functions, more specifically if defined by a generator expression.

First, a little Python riddle.

What is the value of this?

``````[lambda x: x + i + 1
for i in range(24, 42)](0)
``````

Do you think the answer is 25? Any sane person would.

Well, you are wrong. Obviously the answer is 42, as always. Wait . . . wat?

For the moment, let’s do almost the same in a simpler way:

``````l = []
for i in range(24, 42):
l.append(lambda x: x + i + 1)
print(l(0))
``````

And it prints the numbers from 25 to 42. Now, try:

``````>>> i = 4242
>>> print(l(0))
4242
``````

Now it is obvious: the lambda uses the value of `i` of the scope where it is defined. You can do funny things by creating the lambda in the scope of a function with a local, nonlocal or global `i`.

Let’s go back to our problem:

``````>>> [lambda x: x + i + 1 for i in range(24, 42)]
<function <listcomp>.<lambda>>
``````

The `<listcomp>` means that the list comprehension defines its own closure. And in this closure, all the lambda functions take the same value of `i` as it changes. Note that if you use Python 2, the variable `i` is even accessible from the global context as the list comprehension does not define any closure (but generator expressions do, so it’ll work with tuples, sets or dictionaries).

Now, you have some solutions depending on the type of user you are.

• The standard library scout:
``````from functools import partial
• The Guido fanboy (even if Guido is known for disliking `lambda`):
``````[(lambda i: lambda x: x + i + 1)(i)
``````[eval('lambda x: x + i + 1', {'i': i})