In Python we have a way for creating anonymous functions at runtime: lambda. With lambda we can create a function that will not be bond to any name. That is, we don’t need to *def* a function, and lambda can be used instead.

In [1]: f = lambda x: x+1 | |

In [2]: f(1) | |

Out[2]: 2 | |

In [3]: f(3) | |

Out[3]: 4 |

Lambda can also be used to call another function by fixing certain argument:

In [1]: def sum(x, y): | |

...: return x+y | |

...: | |

In [2]: f = lambda n: sum(n,1) | |

In [3]: f(1) | |

Out[3]: 2 | |

In [4]: f(3) | |

Out[4]: 4 |

However, lambda functions use *late binding* for the arguents they get. That is, when you create a lambda function passing a variable as an argument, it’s not immediately copied, a reference to the scope is kept and the value is resolved when the function is called. Thus, if the value of that argument changes within that scope the lambda function will be called with the changed value. Lets see it in action:

In [1]: def sum(x,y): | |

...: return x+y | |

...: | |

In [2]: increment = 1 | |

In [3]: f = lambda n: sum(n,increment) | |

In [4]: f(1) | |

Out[4]: 2 | |

In [5]: f(3) | |

Out[5]: 4 | |

In [6]: increment = 5 | |

In [7]: f(1) | |

Out[7]: 6 |

Unexpected? It depends, but it was definitely unexpected when I run into it. The solution for this is to *bind early*, by copying the value at the time of the creation of the function. We can do this 2 ways:

Using a fixed parameter in the lambda function:

In [1]: def sum(x,y): | |

...: return x+y | |

...: | |

In [2]: increment = 1 | |

In [3]: f = lambda n,j=increment: sum(n,j) | |

In [4]: f(1) | |

Out[4]: 2 | |

In [5]: f(3) | |

Out[5]: 4 | |

In [6]: increment = 5 | |

In [7]: f(1) | |

Out[7]: 2 |

Using functools.partial:

In [1]: from functools import partial | |

In [2]: def sum(x,y): | |

...: return x+y | |

...: | |

In [3]: increment = 1 | |

In [4]: f = pa | |

In [4]: f = partial(sum, increment) | |

In [5]: f(1) | |

Out[5]: 2 | |

In [6]: f(3) | |

Out[6]: 4 | |

In [7]: increment = 5 | |

In [8]: f(1) | |

Out[8]: 2 |

I personally like the second approach, using partial, since its more explicit and I really see option one as a workaround to how lambda functions work.