Python lambda functions are an invaluable feature. One of the benefits of using Python is that it facilitates relatively compact code compared to other programming languages. This means getting so much more done with fewer lines of code.
This isn’t always the case, however. If you’re not aware of the tools python provided in order to achieve this, it is very easy to write verbose code that defeats the point of picking Python for its “compactness”.
One such tool is the lambda function. These allow us to create anonymous functions in python. If you’ve read good python programmers’ code before, you might have come across something that looks like this:
add = lambda a,b : a + b
The code above might look a bit confusing, let me clarify the syntax of a lambda function by breaking it down into its components. Lambda functions have 3 components: the ‘lambda’ keyword (of course), the set of arguments, and an expression.
lambda [(optional) arguments] : [expression]
Before we go into detail about the implementation of lambda functions, let’s first discuss their rules:
Lambda functions are nameless (unless assigned to a variable). You cannot assign a function name after the ‘lambda’ keyword’ as you would with the ‘def’ keyword.
Arguments are optional. Lambda functions can be defined without passing any arguments, just like a regular function.
Lambda functions can only have one expression.
Just like a regular function, you can return anything from a lambda function. It is also possible to return nothing.
Lambda functions can be assigned to variables for repeated use. This is the only way to name a lambda function.
Lambda functions can be returned from regular functions.
Lambda functions can return other lambda functions.
Why Use Lambda Functions?
If you have never used lambda functions before, you probably think that you would do just fine without them, and you’d be right. However, as I’ve stated before, they play an important role in making sure we maintain clean, compact and pythonic code.
Lambda functions are most useful in situations where an anonymous function is required for single-use or repeated use.
As stated before, we can use lambda functions alongside regular functions to generate functions. Let’s create an example where we want to create 3 functions. One that doubles a given number, one that triples a given number, and one that quadruples a given number. We could achieve this by creating 3 different functions:
def doubler(n): return n * 2 def tripler(n): return n * 3 def quadroupler(n): return n * 4
Instead of writing the code above, we could create a function that returns a lambda function with the functionality that we want:
def function_generator(n): return lambda a : a * n
Now we create our desired functions:
doubler = function_generator(2) tripler = function_generator(3) quadroupler = function_generator(4)
function_generator function returns a function that will multiply its argument to whatever argument was passed to
function_generator. We can test this with the following statement:
print(doubler(4), tripler(4), quadroupler(4)) # Output 8 12 16
The function generator can be simplified even further by nesting 2 lambda functions in one line:
function_generator = lambda n : lambda a : a * n
The previous test line should produce the same output as before.
Remember that a lambda function assigned to a variable makes the variable callable as a function. When introducing the topic, I gave the following example:
add = lambda a,b : a + b
This makes ‘add’ callable. So to add 2 numbers, we would use the following statement:
add(4, 6) # Returns 10
This also applies to functions returning lambdas. As long as a lambda function is returned, it is callable, no matter how deep the nesting goes. The function returned also has no name (hence ‘anonymous’) unless it is assigned to a variable.
We can also call a lambda function immediately after its definition:
(lambda x : x * 2)(4) # Returns 8
Make sure to store/print the value returned as it will not be accessible again later on in your module code. This format is very useful for list comprehensions.
Suppose we have a list of numbers (nums) and we want to generate a new list of numbers such that for each number n in nums,
n * 2 > 50 should return
True. How can we achieve this?
Using a regular function and list comprehension:
def validate(n): return n * 2 > 50 nums = [3, 1, 4, 22, 45, 1, 245, 6, 34, 4, 8, 14] nums2 = [n for n in nums if validate(n)] # Returns [45, 245, 34]
However, we could eliminate the function definition altogether and include the validation expression within the list comprehension:
``python nums = [3, 1, 4, 22, 45, 1, 245, 6, 34, 4, 8, 14] nums2 = [n for n in nums if (lambda x : x * 2 > 50)(n)] # Returns [45, 245, 34] ```
Using Python lambda functions makes our code much more compact than in the previous example.