Kodeclik Logo

Our Programs

Courses

Learn More

Schedule

Kodeclik Blog

When would you need a nested lambda in Python?

Remember that lambda functions are unnamed, small, functions that are “use and throw” - defined at a point in a program and used there, and not re-used anywhere. They are typically defined in terms of a single expression and return values based on input arguments. A nested lambda is a lambda inside a lambda and lets see how and when to use it!

Writing without lambdas

Here is a simple Python program that actually uses named functions. First we write a square function that computes the square of a number. Then we write a function that applies the function to every element of a list and thus generate a list of squares:

def square(x):
  return(x*x)

def squares(l):
  return(list(map(square,l)))

print(squares([1,2,3]))

The output is:

[1, 4, 9]

Note that the squares() function uses square() inside it. If the only place you intend to compute squares is for the list [1,2,3] then creating these named functions might be an overkill. We can replace these named functions with lambdas. Here is how that works.

Writing a nested lambda function

Nested lambda function in Python

Let us rewrite the above program to only use lambdas. First, we will replace the outer function with a lambda, like so:

def square(x):
  return(x*x)

#def squares(l):
#  return(list(map(square,l)))

#print(squares([1,2,3]))

print((lambda x: list(map(square,x)))([1,2,3]))

We have commented out the earlier lines so you can see the structure. Note that because the squares() function is no longer available, it is replaced with a lambda in the print function. That lambda function essentially replicates the logic of the original squares() function using an argument called “x”. If we run this program, we will get the same output:

[1, 4, 9]

Now let us replace the inner square() function with a lambda as well. Here is the updated program:

#def square(x):
#  return(x*x)

#def squares(l):
#  return(list(map(square,l)))

#print(squares([1,2,3]))

print((lambda x: list(map((lambda y: y*y),x)))([1,2,3]))

You can see that the square() function is gone (commented out) and in its place is a lambda function that takes “y” as an argument and returns “y*y”. The output is (still):

[1, 4, 9]

In this example the inner and outer lambdas are connected in a purely functional manner. In general, the inner lambda can access variables from the outer lambda. In other words, the function that currently uses “y” as input can also refer to “x” in its body.

Nested lambda function to multiply two numbers

Here is a very simple nested lambda approach to multiply two numbers:

print((lambda x: (lambda y: x*y))(3)(5))

The output is:

15

Note that the outer lambda has argument “x” and the inner lambda has argument “y” but the inner lambda refers to the outer lambda’s argument. Because these are lambda functions each taking one argument, we must pass the arguments one by one, which is what we have done above. We first pass (3) as an argument (which becomes the value of “x”). That returns a lambda (the inner lambda) that simply multiples a number by 3. To this lambda, we are passing 5 as an argument and thus the output is 15.

It is important we pass arguments in the order intended and only as many arguments as intended. If we did something like this:

print((lambda x: (lambda y: x*y))(3,5))

We will get an error:

Traceback (most recent call last):
  File "main.py", line 2, in <module>
    print((lambda x: (lambda y: x*y))(3,5))
TypeError: <lambda>() takes 1 positional argument but 2 were given

This is because remember that each lambda is expecting only one argument (the arguments are listed before the “:” colon).

So we cannot pass arguments in a list. We have to pass them as individual arguments in the order written. But you can pass partial arguments. In other words for a nested lambda that takes one argument to the outer function and one to the inner lambda, it is okay to pass just one argument. Why? What would that do? Lets us try it!

Passing a single argument to a nested lambda

If we do something like this:

print((lambda x: (lambda y: x*y))(6))

The output will be (something like):

<function <lambda>.<locals>.<lambda> at 0x7f00054acaf0>

In other words, Python returns a function because that is what the code above is supposed to do: it returns the inner lambda! We can potentially take the inner lambda, assign it to a variable and use that variable as a function and continue from that point:

mypartialfunction = (lambda x: (lambda y: x*y))(6)
print(mypartialfunction(5))

In the first line we have a nested lambda function. But we passed only one argument to it, so x is assigned the value of 6. Thus, this nested lambda evaluates to: (lambda y: 6*y). That function is now henceforth referred to as “mypartialfunction”. Note that the semantics of mypartial function is that it simply takes one argument (namely, y) and returns 6 times that argument. Thus, in the second line we multiply 6*5 to obtain:

30

To summarize, just like lambdas are “use and throw” functions, nested lambdas are a little bit more complex use and throw functions. They enable you to create more functions on the spot without defining them and enable you to keep your code concise.

If you liked learning about nested lambdas, you should next investigate if you can have a multiline lambda function in Python. These concepts appear closely related but quite different!

For more Python content, checkout the math.ceil() and math.floor() functions! Also
learn about the math domain error in Python and how to fix it!

Interested in more things Python? Checkout our post on Python queues. Also see our blogpost on Python's enumerate() capability. Also if you like Python+math content, see our blogpost on Magic Squares. Finally, master the Python print function!

Want to learn Python with us? Sign up for 1:1 or small group classes.

Kodeclik sidebar newsletter

Join our mailing list

Subscribe to get updates about our classes, camps, coupons, and more.

About

Kodeclik is an online coding academy for kids and teens to learn real world programming. Kids are introduced to coding in a fun and exciting way and are challeged to higher levels with engaging, high quality content.

Copyright @ Kodeclik 2024. All rights reserved.