Python Lambda Functions with EXAMPLES
What is Lambda?
Lambdas, also known as anonymous functions, are small, restricted functions which do not need a name (i.e., an identifier). Lambda functions were first introduced to the field of mathematics by Alonzo Church in the 1930s.
Today, many modern programming languages like Java, Python, C#, and C++ support lambda functions to add functionality to the languages.
In this Lambda tutorial, you will learn:
- What is Lambda?
- Lambdas in Python
- Syntax and Examples
- Using lambdas with Python built-ins
- lambdas in filter()
- lambdas in map()
- lambdas in reduce()
- Why (and why not) use lambda functions?
- Lambdas vs. Regular functions
Lambdas in Python
In Python, lambda expressions (or lambda forms) are utilized to construct anonymous functions. To do so, you will use the lambda keyword (just as you use def to define normal functions).
Every anonymous function you define in Python will have 3 essential parts:
- The lambda keyword.
- The parameters (or bound variables), and
- The function body.
A lambda function can have any number of parameters, but the function body can only contain one expression.
Moreover, a lambda is written in a single line of code and can also be invoked immediately. You will see all this in action in the upcoming examples.
Syntax and Examples
The formal syntax to write a lambda function is as given below:
lambda p1, p2: expression
Here, p1 and p2 are the parameters which are passed to the lambda function. You can add as many or few parameters as you need.
However, notice that we do not use brackets around the parameters as we do with regular functions. The last part (expression) is any valid python expression that operates on the parameters you provide to the function.
Example 1
Now that you know about lambdas let's try it with an example. So, open your IDLE and type in the following:
adder = lambda x, y: x + y
print (adder (1, 2))
Here is the output:
3
Code Explanation
Here, we define a variable that will hold the result returned by the lambda function.
1. The lambda keyword used to define an anonymous function.
2. x and y are the parameters that we pass to the lambda function.
3. This is the body of the function, which adds the 2 parameters we passed. Notice that it is a single expression. You cannot write multiple statements in the body of a lambda function.
4. We call the function and print the returned value.
Example 2
That was a basic example to understand the fundamentals and syntax of lambda. Let's now try to print out a lambda and see the result. Again, open your IDLE and type in the following:
#What a lambda returns
string='some kind of a useless lambda'
print(lambda string : print(string))
Now save your file and hit F5 to run the program. This is the output you should get.
Output:
<function <lambda> at 0x00000185C3BF81E0>
What's happening here? Let's look at the code to understand further.
Code Explanation
- Here, we define a string that you'll pass as a parameter to the lambda.
- We declare a lambda that calls a print statement and prints the result.
But why doesn't the program print the string we pass? This is because the lambda itself returns a function object. In this example, the lambda is not being called by the print function but simply returning the function object and the memory location where it is stored. That's what gets printed at the console.
Example 3
However, if you write a program like this:
#What a lambda returns #2
x="some kind of a useless lambda"
(lambda x : print(x))(x)
And run it by hitting F5, you'll see an output like this.
Output:
some kind of a useless lambda
Now, the lambda is being called, and the string we pass gets printed at the console. But what is that weird syntax, and why is the lambda definition covered in brackets? Let's understand that now.
Code Explanation
- Here is the same string we defined in the previous example.
- In this part, we are defining a lambda and calling it immediately by passing the string as an argument. This is something called an IIFE, and you'll learn more about it in the upcoming sections of this tutorial.
Example 4
Let's look at a final example to understand how lambdas and regular functions are executed. So, open your IDLE and in a new file, type in the following:
#A REGULAR FUNCTION
def girish( funct, *args ):
funct( *args )
def printer_one( arg ):
return print (arg)
def printer_two( arg ):
print(arg)
#CALL A REGULAR FUNCTION
girish( printer_one, 'printer 1 REGULAR CALL' )
girish( printer_two, 'printer 2 REGULAR CALL \n' )
#CALL A REGULAR FUNCTION THRU A LAMBDA
girish(lambda: printer_one('printer 1 LAMBDA CALL'))
girish(lambda: printer_two('printer 2 LAMBDA CALL'))
Now, save the file and hit F5 to run the program. If you didn't make any mistakes, the output should be something like this.
Output:
printer 1 REGULAR CALL
printer 2 REGULAR CALL
printer 1 LAMBDA CALL
printer 2 LAMBDA CALL
Code Explanation
- A function called girish that takes another function as the first parameter and any other arguments following it.
- printer_one is a simple function which prints the parameter passed to it and returns it.
- printer_two is similar to printer_one but without the return statement.
- In this part, we are calling the girish function and passing the printer functions and a string as parameters.
- This is the syntax to achieve the fourth step (i.e., calling the girish function) but using lambdas.
In the next section, you will learn how to use lambda functions with map(), reduce(), and filter() in Python.
Using lambdas with Python built-ins
Lambda functions provide an elegant and powerful way to perform operations using built-in methods in Python. It is possible because lambdas can be invoked immediately and passed as an argument to these functions.
IIFE in Python Lambda
IIFE stands for immediately invoked function execution. It means that a lambda function is callable as soon as it is defined. Let's understand this with an example; fire up your IDLE and type in the following:
(lambda x: x + x)(2)
Here is the output and code explanation:
This ability of lambdas to be invoked immediately allows you to use them inside functions like map() and reduce(). It is useful because you may not want to use these functions again.
lambdas in filter()
The filter function is used to select some particular elements from a sequence of elements. The sequence can be any iterator like lists, sets, tuples, etc.
The elements which will be selected is based on some pre-defined constraint. It takes 2 parameters:
- A function that defines the filtering constraint
- A sequence (any iterator like lists, tuples, etc.)
For example,
sequences = [10,2,8,7,5,4,3,11,0, 1]
filtered_result = filter (lambda x: x > 4, sequences)
print(list(filtered_result))
Here's the output:
[10, 8, 7, 5, 11]
Code Explanation:
1. In the first statement, we define a list called sequences which contains some numbers.
2. Here, we declare a variable called filtered_result, which will store the filtered values returned by the filter() function.
3. A lambda function which runs on each element of the list and returns true if it is greater than 4.
4. Print the result returned by the filter function.
lambdas in map()
the map function is used to apply a particular operation to every element in a sequence. Like filter(), it also takes 2 parameters:
- A function that defines the op to perform on the elements
- One or more sequences
For example, here is a program that prints the squares of numbers in a given list:
sequences = [10,2,8,7,5,4,3,11,0, 1]
filtered_result = map (lambda x: x*x, sequences)
print(list(filtered_result))
Output:
[100, 4, 64, 49, 25, 16, 121, 0, 1]
[KR1]
Code Explanation:
- Here, we define a list called sequences which contains some numbers.
- We declare a variable called filtered_result which will store the mapped values
- A lambda function which runs on each element of the list and returns the square of that number.
- Print the result returned by the map function.
lambdas in reduce[vV2][J3]()
The reduce function, like map(), is used to apply an operation to every element in a sequence. However, it differs from the map in its working. These are the steps followed by the reduce() function to compute an output:
Step 1) Perform the defined operation on the first 2 elements of the sequence.
Step 2) Save this result
Step 3) Perform the operation with the saved result and the next element in the sequence.
Step 4) Repeat until no more elements are left.
It also takes two parameters:
- A function that defines the operation to be performed
- A sequence (any iterator like lists, tuples, etc.)
For example, here is a program that returns the product of all elements in a list:
from functools import reduce
sequences = [1,2,3,4,5]
product = reduce (lambda x, y: x*y, sequences)
print(product)
Here is the output:
120
Code Explanation:
- Import reduce from the functools module
- Here, we define a list called sequences which contains some numbers.
- We declare a variable called product which will store the reduced value
- A lambda function that runs on each element of the list. It will return the product of that number as per the previous result.
- Print the result returned by the reduce function.
Why (and why not) use lambda functions?
As you will see in the next section, lambdas are treated the same as regular functions at the interpreter level. In a way, you could say that lambdas provide compact syntax for writing functions which return a single expression.
However, you should know when it is a good idea to use lambdas and when to avoid them. In this section, you will learn some of the design principles used by python developers when writing lambdas.
One of the most common use cases for lambdas is in functional programming as Python supports a paradigm (or style) of programming known as functional programming.
It allows you to provide a function as a parameter to another function (for example, in map, filter, etc.). In such cases, using lambdas offer an elegant way to create a one-time function and pass it as the parameter.
When should you not use Lambda?
You should never write complicated lambda functions in a production environment. It will be very difficult for coders who maintain your code to decrypt it. If you find yourself making complex one-liner expressions, it would be a much superior practice to define a proper function. As a best practice, you need to remember that simple code is always better than complex code.
Lambdas vs. Regular functions
As previously stated, lambdas are[vV4][J5] just functions which do not have an identifier bound to them. In simpler words, they are functions with no names (hence, anonymous). Here is a table to illustrate the difference between lambdas and regular functions in python.
Lambdas
Regular Functions
Syntax:
lambda x : x + x
Syntax:
def (x) :
return x + x
Lambda functions can only have one expression in their body.
Regular functions can have multiple expressions and statements in their body.
Lambdas do not have a name associated with them. That's why they are also known as anonymous functions.
Regular functions must have a name and signature.
Lambdas do not contain a return statement because the body is automatically returned.
Functions which need to return value should include a return statement.
Explanation of the differences?
The primary difference between a lambda and a regular function is that the lambda function evaluates only a single expression and yields a function object. Consequently, we can name the result of the lambda function and use it in our program as we did in the previous example.
A regular function for the above example would look like this:
def adder (x, y):
return x + y
print (adder (1, 2))
Here, we have to define a name for the function which returns the result when we call it. A lambda function doesn't contain a return statement because it will have only a single expression which is always returned by default. You don't even have to assign a lambda either as it can be immediately invoked (see the next section). As you will see in the following example, lambdas become particularly powerful when we use them with Python's built-in functions.
However, you may still be wondering how lambdas are any different from a function that returns a single expression (like the one above). At the interpreter level, there is not much difference. It may sound surprising, but any lambda function that you define in Python is treated as a normal function by the interpreter.
As you can see in the diagram, the two definitions are handled in the same way by the python interpreter when converted to bytecode. Now, you cannot name a function lambda because it is reserved by Python, but any other function name will yield the same bytecode[KR6].
Summary
- Lambdas, also known as anonymous functions, are small, restricted functions which do not need a name (i.e., an identifier).
- Every lambda function in Python has 3 essential parts:
- The lambda keyword.
- The parameters (or bound variables), and
- The function body.
- The syntax for writing a lambda is: lambda parameter: expression
- Lambdas can have any number of parameters, but they are not enclosed in braces
- A lambda can have only 1 expression in its function body, which is returned by default.
- At the bytecode level, there is not much difference between how lambdas and regular functions are handled by the interpreter.
- Lambdas support IIFE thru this syntax: (lambda parameter: expression)(argument)
- Lambdas are commonly used with the following python built-ins:
- Filter: filter (lambda parameter: expression, iterable-sequence)
- Map: map (lambda parameter: expression, iterable-sequences)
- Reduce: reduce (lambda parameter1, parameter2: expression, iterable-sequence)
- Do not write complicated lambda functions in a production environment because it will be difficult for code-maintainers.