Lambdas
- VC Healy
- May 23, 2020
- 2 min read
Small functions and the lambda expression
Little functions that act as predicates or that combine elements in some way.
If there’s a Python built-in or a module function that’s suitable, you don’t need to define a new function at all:
stripped_lines = [line.strip() for line in lines]
existing_files = filter(os.path.exists, file_list)
If the function you need doesn’t exist, you need to write it. One way to write small functions is to use the lambda expression.
lambda takes a number of parameters and an expression combining these parameters, and creates an anonymous function that returns the value of the expression:
adder = lambda x, y: x+y
print_assign = lambda name, value: name + '=' + str(value)
An alternative is to just use the def statement and define a function in the usual way:
def adder(x, y):
return x + y
def print_assign(name, value):
return name + '=' + str(value)
Which alternative is preferable?
That’s a style question
One reason is that lambda is quite limited in the functions it can define. The result has to be computable as a single expression, which means you can’t have multiway if... elif... else comparisons or try... except statements.
If you try to do too much in a lambda statement, you’ll end up with an overly complicated expression that’s hard to read.
Quick, what’s the following code doing?
import functools
total = functools.reduce(lambda a, b: (0, a[1] + b[1]), items)[1]
You can figure it out, but it takes time to disentangle the expression to figure out what’s going on.
Using a short nested def statements makes things a little bit better:
import functools
def combine(a, b):
return 0, a[1] + b[1]
total = functools.reduce(combine, items)[1]
But it would be best of all if I had simply used a for loop:
total = 0
for a, b in items:
total += b
Or the sum() built-in and a generator expression:
total = sum(b for a, b in items)
Many uses of functools.reduce() are clearer when written as for loops.
Fredrik Lundh once suggested the following set of rules for refactoring uses of lambda:
Write a lambda function.
Write a comment explaining what the heck that lambda does.
Study the comment for a while, and think of a name that captures the essence of the comment.
Convert the lambda to a def statement, using that name.
Remove the comment.
Kommentare