Today we’ll be talking about lambda expressions that are used to return anonymous functions, so functions without a name.
Here’s the video version of this article:
Table of Contents
Lambda Expressions vs the def Statement
Lambda expressions are another way of defining functions, besides the def statement. There are a couple of differences between the two:
First, lambda is an expression and can appear where a statement can’t, like for example in a list literal or as an argument passed to a function.
Second, lambda defines an anonymous function, whereas def defines a named function.
Third, def defines a function in one place in the code and the function is then referenced by name in another place in the code, whereas lambda defines inline functions.
Let’s define a function using the def statement and then using a lambda expression to see the difference.
Here’s a def-defined function – definition and call.
def repeat(word, times):
return (word + " ") * times
print(f"And then he said: {repeat('no', 3)}")
The output is:
And then he said: no no no
And here’s how we would define the same function using a lambda expression:
print(f"And then he said: {(lambda word, times: (word + ' ') * times)('no', 3)}")
The output is now the same. As you can see, the syntax of a lambda expression is as follows:
lambda args: expression
where args is an arbitrary number of arguments and expression is the expression which makes use of the arguments.
If we compare def functions with lambda functions, we can see the following:
The arguments in a lambda expression correspond to the parameters of the def function and the expression in the lambda corresponds to the value returned by the def function.
Named Lambdas
As you can see, we don’t assign the lambda function to a name. We’re first defining the function inline inside the print function and then calling it directly there by passing the arguments in parentheses like so:
But if we wanted, we could assign the lambda function to a name, too. Here’s how:
repeat = lambda word, times: (word + ' ') * times
print(f"And then he said: {repeat('no', 3)}")
Using Lambda Expressions
Lambdas are used for simple short functions, especially ones that are supposed to be called only once, although you can naturally call them multiple times if you assign them to variables like above.
Lambda functions are limited to just a single expression, not a block of code. If you need a more complex code in your function, go with def instead.
Lambda Expressions Inside Lists
Lambdas are often used inside lists and dictionaries. Here’s an example of a list:
functions = [lambda x: 2 * x + 3,
lambda x: 2 ** x - 1,
lambda x: 10 / (5 + x)]
for f in functions:
print(f(5))
The output is:
13
31
1.0
We usually use lambdas like this if we want to avoid defining functions in a different part of the program just to use them once. Besides, it could be difficult to come up with some sensible names for such functions.
There’s one more thing worth mentioning. The arguments in the lambda expressions are local inside the lambda expression, so each of the three functions in the list has its own local x argument, just like the arguments passed to a function defined with def.
Lambdas inside Dictionaries
Now let’s have an example with a dictionary:
actions = {'slice': lambda word: word[:3],
'repeat': lambda word: (word + ' ') * 3,
'separate': lambda word: '-'.join(word)}
action = input("Should I slice, repeat or separate?: ")
print(actions[action]("awesome"))
Here’s a possible output:
Should I slice, repeat or separate?: separate
a-w-e-s-o-m-e
Expressions Used in Lambdas
You can use all kinds of expressions in lambdas. Calling a function or using the ternary if expression works too.
In the following example we’ll use the print function in the lambda expression:
>>> greet = lambda name: print(f"Hi, {name}!")
>>> greet("Maggie")
Hi, Maggie!
And in the following example we’ll use a ternary if expression:
>>> confirm_one = lambda x: "one" if x == 1 else "not one"
>>> confirm_one(1)
'one'
>>> confirm_one(2)
'not one'
Nested Lambdas and Closures
And just one last thing about lambdas: Lambdas can be nested. Although nested lambdas do not contribute to the readability of your code, it can be done. You can create closures with lambdas just like with functions defined with def.
I have an article about closures if you want to learn more about them, but to be brief a closure is a function returned by another function which remembers the variables local to the enclosing function. I don’t want to go into too much detail here because this article is not about closures and besides, closures are not typically defined with lambdas, but feel free to read my closures article if you’re interested in this topic.
Have a look:
>>> mult = lambda x: lambda y: x * y
>>> a = mult(10)
>>> a(5)
50