How to use lambda functions in Python

Lambda functions have been a method for functional programming since Python 1.0. However, in recent years, other techniques have gained greater popularity and largely replaced lambdas. Nevertheless, there are still some specialized uses for lambdas that savvy Python programmers should know.

What are lambda functions in Python?

In Python, lambda function refers to an anonymous function. Python uses the lambda keyword to create a lambda function. A lambda expression consists of the lambda keyword followed by a list of arguments, a colon and a single expression. The expression is provided with the arguments and evaluated when the lambda function is called:

lambda argument: expression

Functions are a fundamental language construct in almost every programming language, and they represent the smallest reusable unit of code. Typically, functions in Python are defined with the def keyword. We’ll show you the square function that multiplies a number by itself as an example:

# Define square function
def square(num):
    return num * num
# Show that it works
assert square(9) == 81

The def keyword is a well-known way to define functions in Python, but the language also has lambdas. These are anonymous functions that define an expression with parameters. Lambdas can be used anywhere where a function is expected or can be assigned to a name. You can see the lambda expression equivalent to the square function here:

# Create square function
squared = lambda num: num * num
# Show that it works
assert squared(9) == 81

In Python, lambda function refers to a function created with the lambda keyword. Lambda is not the name of a specific function nor is it one of the Python operators.

What is the difference between lambda and def?

It may seem strange that Python lets you create functions with both lambda and def. However, Lambda is not its own feature, rather just another way to create short functions locally. Every function created with lambda can also be created with def. However, this is not the case the other way around.

At the syntactic level, lambda and def are both keywords. One key difference between them is Python’s strict statement and expression separation. Statements are steps in executing code, while expressions are evaluated to a value.

Def begins a statement, or more specifically a compound statement, which contains further statements. Only return statements may appear within a def statement. A return statement returns a value when the function defined with def is called.

Unlike the def statement, lambda starts an expression which cannot contain any statements. The lambda expression takes one or more arguments and returns an anonymous function. When the lambda function is called, the expression contained in it is evaluated with the passed arguments and it is returned.

What are the limitations of Python’s lambda expressions?

Python has purposely limited the usefulness of lambda functions, as it is usually better to name functions. This forces programmers to think about the function’s meaning and to distinguish parts clearly.

Lambdas cannot contain instructions, unlike the body of a function defined with the def keyword. It is therefore not possible to use if, for, etc. in a lambda function. It is also not possible to trigger an exception, as this requires a raise statement.

Lambda functions in Python may contain a single expression which is evaluated when called. Type annotations cannot be used within the lambda expression. Nowadays, most use cases of lambda functions in Python use other techniques, such as comprehensions.

Different uses for lambda functions in Python

Lambdas are derived from functional programming. In some languages, such as JavaScript, anonymous functions are widely used without needing a special keyword. In Python, lambda expressions are used to create small functions locally. We’ll go over their most useful applications below.

How to populate higher order functions in Python with lambdas

Lambdas are often used with higher-order functions like map(), filter() and reduce(). The elements of an iterable can be transformed without the using loops thanks to lambdas. Higher-order functions are functions that take functions as parameters or return a function.

The map() function takes a function and an iterable as parameters. It executes the function for each element of the iterable. Let’s try generating square numbers. We use the map() function and pass a lambda expression as an argument, which generates the square function. The square function is applied to each element of the list with map():

nums = [3, 5, 7]
# Square numbers using `map()` and `lambda`
squares = map(lambda num: num ** 2, nums)
# Show that it works
assert list(squares) == [9, 25, 49]

Starting with Python 3.0, the map() and filter() functions return an iterable instead of a list. A list() call is used inside the assert statements to unpack iterables into a list.

List comprehensions offer a more modern approach for processing iterables. Instead of resorting to map() and generating a lambda function, we can describe the operation directly:

nums = [3, 5, 7]
# Square numbers using list comprehension
squares = [num ** 2 for num in nums]
# Show that it works
assert squares == [9, 25, 49]

The filter() function can be used to filter the elements of an iterable. We can extend our example to generate only even square numbers:

# List of numbers 1-4
nums = [1, 2, 3, 4]
# Square each number
squares = list(map(lambda num: num ** 2, nums))
# Filter out the even squares
even_squares = filter(lambda square: square % 2 == 0, squares)
# Show that it works
assert list(even_squares) == [4, 16]

We show the preferred approach of using list comprehension to generate the same result without using lambdas and higher-order functions. The if part of the comprehension is used to filter out the even numbers from the generated square numbers:

# List of numbers 1-4 squared
squares = [num ** 2 for num in range(1, 5)]
# Filter out the even squares
even_squares = [square for square in squares if square % 2 == 0]
# Show that it works
assert even_squares == [4, 16]

Python’s reduce() function hasn’t been included in the standard library since Python 3.0. This function can be found in the functools module.

How to implement key functions in Python with lambdas

Comprehensions have largely replaced the classic higher-order functions map() and filter() in Python. However, key functions can be used to demonstrate lambdas’ full strengths.

The Python comparison functions sorted(), min() and max() operate on iterables. Each element of the iterable is subjected to a comparison when called. The three functions take a key function as an optional key parameter. The key function is called for each element and returns a key value for the comparison operation.

Let’s consider the following problem. We have a folder with image files where the names are mapped to a Python list. We want to sort the list. The filenames all start with img, followed by a number:

# List of image file names
images = ['img1', 'img2', 'img30', 'img3', 'img22', 'img100']

If we use Python’s sorted() function, the lexicographic order is used. This treats consecutive digits as single numbers. Thus, the numbers ['1', '2', '100'] are put in the order ['1', '100', '2']. The result is not as we expect:

# Sort using lexicographic order
sorted_image = sorted(images)
# Show that it works
assert sorted_image == ['img1', 'img100', 'img2', 'img22', 'img3', 'img30']

We pass a lambda expression that produces a key function to ensure the sorting is correct. The key function extracts the numeric part of a filename, which is used as a key by sorted():

# Extract numeric component and sort as integers
sorted_image = sorted(images, key=lambda name: int(name[3:]))
# Show that it works
assert sorted_image == ['img1', 'img2', 'img3', 'img22', 'img30', 'img100']

The key function is used locally and once only. It’s not necessary to define an extra named function for it. Lambdas are the correct way to create key functions. Let’s take a look at two more examples.

Like sorted(), the built-in Python functions min() and max() take an optional key function. The functions find the smallest and largest element in a list or other iterable. The smallest or largest element is a matter of definition and can be specified using the key function.

It is clear what is meant by smallest or largest element for lists of simple values, such as a list of numbers. We do not need a special key function in this case:

nums = [42, 69, 51, 13]
assert min(nums) == 13
assert max(nums) == 69

If no key function is passed, the identity function f(x) = x is used as a default. This can easily be defined as a Python lambda with lambda x: x.

But what if each element of an iterable includes multiple dates? Let’s imagine a list of dicts representing people with their names and ages. What is the criteria for min() and max() when deciding which is the smallest and largest element? This is where a key function is useful.

We need sample data to illustrate how key functions work. Let’s create a function Person() which serves as a constructor:

# Constructor function for dict representing a person
def Person(name, age):
    return {'name': name, 'age': age}
# Check that it works as expected
assert Person('Jim', 42) == {'name': 'Jim', 'age': 42}

We create a list of people using our constructor function:

# Create list of people
people = [person('Jim', 42), person('Jack', 51), person('John', 69)]

We find the oldest person using the max() call. This generates a key function using the lambda expression, which takes a person dict and extracts the age from it as a comparison element:

# Find the oldest person
oldest = max(people, key=lambda person: person['age'])
# Check that it works
assert oldest == Person('John', 69)

The approach works exactly the same for the min() function. In this case, we’ll define the key function outside the min() call and use a lambda expression again. This improves readability and is worthwhile if the key function has multiple local uses:

# Define key function to compare people by age
by_age = lambda person: person['age']
# Find the youngest person
youngest = min(people, key=by_age)
# Check that it works
assert youngest == Person('Jim', 42)

How to create closures with Python lambdas

Python lambdas are also used when defining closures. These are functions that are created by other functions and store a value. Closures can be used to create families of similar functions. We’ll show a common example where power functions are created.

Power functions take an argument and exponentiate it. The square function f(x) = x ^ 2 and the cubic function f(x) = x ^ 3 are well-known examples. Arbitrary power functions can be generated as closures using a constructor function. We’ll use a lambda expression which means we do not have to define an inner named function:

# Define constructor function for power functions
def power(n):
    return lambda num: num ** n
# Create square and cubic functions as closures
square = power(2)
cubic = power(3)
# Show that it works
assert square(10) == 100
assert cubic(10) == 1000

How to use immediately invoked function expression (IIFE) with Python lambdas

IIFE, pronounced “iffy”, is a known pattern in JavaScript. It involves defining an anonymous function and executing it immediately.

Lambdas can be used as IIFEs, although they are not very useful due to limitations in Python. We only need to put parentheses around the lambda expression:

(lambda num: num * num)

And another pair of parentheses containing the argument(s):

assert (lambda num: num * num)(3) == 9

For Python beginners, we recommend taking a look at our Python tutorial.

We use cookies on our website to provide you with the best possible user experience. By continuing to use our website or services, you agree to their use. More Information.