Many functions or classes require a callback as a parameter. For example, map requires a callback as the first parameter. Creating a function might be too much in this case if the logic is too simple. Lambda can be used for this purpose to pass a callback with simple logic without a function name.
Syntax
The syntax is simple.
lambda arguments: "logic here"
It’s not possible to write multiple lines.
Use lambda without argument
If it’s not necessary to use any arguments, omit them and write the logic only at the right side.
fn = lambda: print("Hello World!")
fn()
# Hello World!
Note that it’s not a good design to assign a lambda function to a variable. Pylint shows a warning on the line.
Lambda expression assigned to a variable. Define a function using the "def" keyword instead.pylint(unnecessary-lambda-assignment)
Lambda should be used where a function requires a callback.
Lambda with multiple arguments
If multiple arguments are needed, add the parameters to the left side.
fn2 = lambda x, y, z: print(f"(x, y, z): ({x}, {y}, {z})")
fn2(11, 22, 33)
# (x, y, z): (11, 22, 33)
Lambda with named parameter and keyword parameter
Named parameters and keyword parameters are also possible to use.
fn3 = lambda x, *args, y, **kwargs: print(
f"x: {x}, args: {args}, y: {y}, kwargs: {kwargs}"
)
fn3(11, 12, 13, 14, y=55, example_arg1=1, example_arg2=22)
# x: 11, args: (12, 13, 14), y: 55, kwargs: {'example_arg1': 1, 'example_arg2': 22}
Lambda with ternary operator
The logic needs to be written in one line but the ternary operator can be used.
fn4 = lambda found: print("found") if found else print("not found")
fn4(True) # found
fn4(False) # not found
Lambda with Multiple lines
I mentioned that the logic needs to be written in a single line. That’s true. However, we could have a trick here. If it is a list, multiple things can be done in the lambda function.
fn5 = lambda x: [res := x + x, res := res + res + x, print(res)]
fn5(1) # 5
It does 3 things. If I write it in 3 lines, it looks like this.
res = x + x
res = res + res + x
print(res)
I don’t recommend this way because it looks ugly. It’s not readable. If multiple lines are needed, create a named function instead.
Can original value be updated in a lambda function?
What if we pass an object as a parameter? Is it updated in the function? It’s not.
fn6 = lambda data: [data := [3, 4], data := [data[0] + data[1]], print(data)]
data = [1, 2]
fn6(data)
print(data)
# [7]
# [1, 2]
The original data
variable keeps the same values.
It’s not possible to assign a value to the origin parameter.
# Parsing failed: 'cannot assign to subscript here. Maybe you meant '==' instead of '='? (<unknown>, line 36)'pylint(syntax-error)
fn7 = lambda data: [data[0] = 1, print(data)]
If it is a function, the original variable could be updated. Using lambda for simple logic is better to avoid this mistake.
def update_list_data(data):
data[0] = 11
data = [1, 2]
update_list_data(data)
print(data)
# [11, 2]
When is lambda actually used?
We learned how to define lambda but when can we actually use it? We can use it if a function requires a callback.
data_list = [1, 2, 3, 4, 5]
result = map(lambda x: x * x, data_list)
print(list(result))
# [1, 4, 9, 16, 25]
data_list2 = [("AAA", 35), ("BBB", 12), ("CCC", 92), ("DDD", 22)]
data_list2.sort(key=lambda data: data[1])
print(data_list2)
# [('BBB', 12), ('DDD', 22), ('AAA', 35), ('CCC', 92)]
Lambda is a good choice if the logic is clear and simple enough.
Comments