** Lambda Lambda Lambda
:PROPERTIES:
:date: 2013/05/20 10:13:11
:updated: 2013/06/26 18:56:48
:categories: programming
:END:
Is that some kind of fraternity? of anonymous functions? What is that!? There are many times where you need a callable, small function in python, and it is inconvenient to have to use =def= to create a named function. Lambda functions solve this problem. Let us look at some examples. First, we create a lambda function, and assign it to a variable. Then we show that variable is a function, and that we can call it with an argument.
#+BEGIN_SRC python
f = lambda x: 2*x
print f
print f(2)
#+END_SRC
#+RESULTS:
: at 0x0000000001E6AAC8>
: 4
We can have more than one argument:
#+BEGIN_SRC python
f = lambda x,y: x + y
print f
print f(2, 3)
#+END_SRC
#+RESULTS:
: at 0x0000000001E3AAC8>
: 5
And default arguments:
#+BEGIN_SRC python
f = lambda x, y=3: x + y
print f
print f(2)
print f(4, 1)
#+END_SRC
#+RESULTS:
: at 0x0000000001E9AAC8>
: 5
: 5
It is also possible to have arbitrary numbers of positional arguments. Here is an example that provides the sum of an arbitrary number of arguments.
#+BEGIN_SRC python
import operator
f = lambda *x: reduce(operator.add, x)
print f
print f(1)
print f(1, 2)
print f(1, 2, 3)
#+END_SRC
#+RESULTS:
: at 0x0000000001DFAAC8>
: 1
: 3
: 6
You can also make arbitrary keyword arguments. Here we make a function that simply returns the kwargs as a dictionary. This feature may be helpful in passing kwargs to other functions.
#+BEGIN_SRC python
f = lambda **kwargs: kwargs
print f(a=1, b=3)
#+END_SRC
#+RESULTS:
: {'a': 1, 'b': 3}
Of course, you can combine these options. Here is a function with all the options.
#+BEGIN_SRC python
f = lambda a, b=4, *args, **kwargs: (a, b, args, kwargs)
print f('required', 3, 'optional-positional', g=4)
#+END_SRC
#+RESULTS:
: ('required', 3, ('optional-positional',), {'g': 4})
One of the primary limitations of lambda functions is they are limited to single expressions. They also do not have documentation strings, so it can be difficult to understand what they were written for later.
*** Applications of lambda functions
Lambda functions are used in places where you need a function, but may not want to define one using =def=. For example, say you want to solve the nonlinear equation $\sqrt{x} = 2.5$.
#+BEGIN_SRC python
from scipy.optimize import fsolve
import numpy as np
sol, = fsolve(lambda x: 2.5 - np.sqrt(x), 8)
print sol
#+END_SRC
#+RESULTS:
: 6.25
Another time to use lambda functions is if you want to set a particular value of a parameter in a function. Say we have a function with an independent variable, $x$ and a parameter $a$, i.e. $f(x; a)$. If we want to find a solution $f(x; a) = 0$ for some value of $a$, we can use a lambda function to make a function of the single variable $x$. Here is a example.
#+BEGIN_SRC python
from scipy.optimize import fsolve
import numpy as np
def func(x, a):
return a * np.sqrt(x) - 4.0
sol, = fsolve(lambda x: func(x, 3.2), 3)
print sol
#+END_SRC
#+RESULTS:
: 1.5625
Any function that takes a function as an argument can use lambda functions. Here we use a lambda function that adds two numbers in the =reduce= function to sum a list of numbers.
#+BEGIN_SRC python
print reduce(lambda x, y: x + y, [0, 1, 2, 3, 4])
#+END_SRC
#+RESULTS:
: 10
We can evaluate the integral $\int_0^2 x^2 dx$ with a lambda function.
#+BEGIN_SRC python
from scipy.integrate import quad
print quad(lambda x: x**2, 0, 2)
#+END_SRC
#+RESULTS:
: (2.666666666666667, 2.960594732333751e-14)
*** Summary
Lambda functions can be helpful. They are never necessary. You can always define a function using =def=, but for some small, single-use functions, a lambda function could make sense. Lambda functions have some limitations, including that they are limited to a single expression, and they lack documentation strings.