What are lambda functions?

In lambda calculus, lambda functions are functions without a nmae. From mathematics, the same idea has found its way into computer programming languages.

So, defining it formally

A lambda function is a function without any name.

Other common names used to refer to lambda functions are lambda expressions, lambda abstractions, function literals and anonymous functions.

All these different terms make perfect sense:

  1. Lambda functions are expressions unlike normal functions in programming languages (defined using def in the case of Python) which are statements. Hence, they are also known as lambda expressions.
  2. Lambda functions are abstractions over the long way of defining named functions in given languages. In Python, as we shall see below the abstraction brought about by lambda functions over normal function definition is fairly considerable. Hence, they are also known as lambda abstractions.
  3. Just like 10 denotes an integer directly, as is, a lambda function denotes a function directly. That is, a lambda function is a literal for the function data type. Hence, lambda functions are also known as function literals.
  4. A lambda function, as stated before, doesn't have a name of its own. In other words, it's an anonymous function. Hence lambda functions are also known as anonymous functions.

All functional programming languages, including Python, provide support for lambda functions, in some way.

These functions are meant to define simple and short functions, mostly one-liner, that perform a computation and return its result.

Let's explore lambdas provided by the Python programming language.

Lambda functions in Python

In Python, a lambda function can be created via a similar sounding keyword — lambda.

Shown below is the syntax of lambda when used to define a function without any parameters:

lambda: expression

First comes the keyword and then a valid Python expression. This expression is evaluated and returned when the lambda function is invoked.

Let's consider a quick example:

x = lambda: 100

Here we create a lambda function that returns 100 when called, and then save it in the variable x. Next we invoke x.

And here's what we get


The value 100 printed to the shell. Not even a pinch difficult, is it?

Moving on, it's also possible to define parameters in a lambda function.

Shown below is the syntax to do so:

lambda parameters: expression

As before, it begins with the lambda keyword. Then comes a list of parameters just as they would be specified inside the pair of parentheses in a normal function definition.

Lastly, comes the expression after the : colon. All parameters of the lambda function are accessible in expression — otherwise, what would be the point of even having them!

Below we create a couple of lambda functions having parameters.

First, let's consider a simple doubler function — you give it a number as argument and it returns back its double:

double = lambda x: x * 2

Next, let's consider a simple summer: you give it two nums and it returns back their sum.

sum = lambda a, b: a + b
sum(10, 20)
sum(5, 2.5)
sum(120, -5)

Why not create a function to retrieve the first element of any given sequence?

Let's put up a more complex lambda function computing the distance between two co-ordinates on a Cartesian plane.

Each co-ordinate ought to be provided as a tuple (or at least an iterable) of two elements, whose first item is the x value while the second value is the y value.

distance = lambda a, b: ((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2) ** 0.5

Below, we compute the distances between a couple of Cartesian co-ordinates:

distance((0, 5), (1, 1))
distance((0, 0), (3, 4))

More on lambda

As we saw above, constructing lambda functions in Python is very easy. Just write the lambda keyword an optional list of parameters, and then an expression — that's it. You have a functional function in hand!

However, there are some hidden details regarding lambdas in Python that we must know in order to keep from using them in incorrect ways.

They are discussed as follows:

Multiple statements can't be given

One might think that it's possible to put multiple statements inside a lambda function by separating them using a ; semi-colon.

However, if we do so, what would happen is something else.

Consider the following code and try to think what would happen here:

f = lambda x: x + 5; print('Hello')

This code is perfectly valid — it doesn't have any syntax errors. But it surely has a semantic error. That is, the code doesn't work out as it's expected to.

As soon as the code gets executed, we get 'Hello' printed regardless of whether we call f() or not. In fact, we get no output, when we call f(), which is what we actually desire.

So why does this happen?

The semi-colon in the code above separates the two statements f = lambda x: x + 5 and print('Hello'), contrary to what some might think that it separates the two expressions x + 5 and print('Hello').

The code is similar to the following:

f = lambda x: x + 5

So, in short, it's not possible to have multiple statements inside a lambda function.

co_name on lambdas returns '<lambda>'

Although a lambda function is an anonymous function i.e has no name, the co_name attribute of its code object holds the string '<lambda>'. This is to indicate that the underlying function is a lambda function.

The following snippet demonstrates this:

f = lambda x: x
The word '<lambda>' can't be the name of a normal function in Python, since it contains two invalid characters: < and >.

Practical usage of lambda

In the section above, we considered a bunch of lambda functions each of which accomplished a particular task. For instance, the one in sum added two number, the one in distance calculated the distance between two points on a Cartesian plane and so on.

However, such function could be better defined using normal function definition syntax. Why?

That's because all these functions do something that could be better understood by a name. Moreover, these functions aren't meant for short use, rather they are meant to be used again and again.

For instance, when we create a function to sum two arguments, at the end of the day, we save it in a variable named sum. In other words, we aim to describe the function's purpose using a name, which in this case technically belongs to a variable, not to the function itself.

Anonymous functions aren't meant for such scenarios. What's the point of leaving out the name of the function, when you have to name it, indirectly, later on?

Lambda expressions are meant for places where short, simple functions are desired, naming which would be unnecessary and just overcomplicate things.

Suppose we want to sort the following two lists in ascending order: the first one based on the length of each string, while the second one based on the second item of each tuple:

a = ['Hello', 'Bye', 'My', 'Lovely', 'Incorporation', 'Hi']
b = [(0, 5), (2, -1), (10, 5), (2, -5), (0, 0), (-1, 1)]

As we know back from the Python List Sorting, this could be achieved using the sort() method, along with its key parameter.

For the first list, we need to provide as key, a function that returns the length of a given list element. For the second list, we need to provide a function that returns the second item of a given list element.

Now, if we go the normal way to define these functions, we'd get something like:

a = ['Hello', 'Bye', 'My', 'Lovely', 'Incorporation', 'Hi']
b = [(0, 5), (2, -1), (10, 5), (2, -5), (0, 0), (-1, 1)]

def get_length(item):
    return len(item)

def get_second_item(item):
    return item[1]


See how we have an unnecessary name for each of the given functions get_length() and get_second_item(). The names are clearly redundant — they overcrowd the global namespace for no reason whatsoever.

This is what lambda functions were made for i.e create functions that don't need to be named.

Let's rewrite the code above using lambda functions instead of get_length() and get_second_item():

a = ['Hello', 'Bye', 'My', 'Lovely', 'Incorporation', 'Hi']
b = [(0, 5), (2, -1), (10, 5), (2, -5), (0, 0), (-1, 1)]

a.sort(key=lambda x: len(x))
b.sort(key=lambda x: x[1])

First of all, it's clearly apparent that this code is much simpler and shorter than the previous one. Secondly, we aren't crowding the global namespace with unnecessary function names at all.

When calling sort(), we need to rightaway provide a function to it as key. Mostly, key functions are simple and short, which goes with the whole essence of lambdas.

To boil it all down, lambda functions are useful in cases where specifically naming a simple, sleek function is not really required.