Python’s syntax is relatively convenient and easy to work with, but aside from the basic structure of the language Python is also sprinkled with small syntax structures that make certain tasks especially convenient. The
lambda keyword/function construct is one of these, where the creators call it “syntactical candy”. Here we’ll examine how to use them.
To understand the
lambda keyword/function and their constructs we must first review how regular function definitions work in Python. The following is the basic structure of a function definition:
def basic(arg): # Or whatever the function does pass # Or whatever the function returns return arg
What we’ve defined here is essentially an empty function named basic, which receives one argument, does nothing (the pass statement is essentially a valid “do nothing” statement), and then returns the argument it was given. This is the most basic structure of most functions, but the simplest function definition would only include one of these statements – in one statement it would either do something (or pass), or return something or
return statement always returns at least the
None instance, so it can’t actually return nothing). Here is how these two cases would look:
def simple1(arg): pass def simple2(arg): return arg
Notice how we also saved a line by putting the function body statements on the same line as the definition statement. A
lambda function structure is exactly the latter of these two structures, i.e. a one-statement function which returns something, the difference being that the “return” keyword is implied and doesn’t show up in the construct. Now that we know how
lambda functions work (identically to a one-statement function), let’s construct the simple2 function in
lambda form. To do this, we simply use the
lambda construct – if we call our
lambda function simplest, it would be like so:
simplest = lambda arg: arg
And that’s it! Now we have simplest and simple2 which behave the exact same way, but the former we constructed with much less jargon; however, technically speaking we only saved two characters in this case, so what’s the big deal?
If we look in detail at the
lambda statement we find that it is actually a statement that returns a function (which is why we assign it to a variable), and this is where the real power of the
lambda construct is, so let’s look at an example where we harness this power.
Let’s say we have a list of 3-tuples which looks like this:
tups = [ (1, 3, -2), (3, 2, 1), (-1, 0, 4), (0, -1, 3), (-2, 6, -5) ]
If we want a sorted version of tups we’d simply have to give it to the built-in
>>> sorted(tups) [(-2, 6, -5), (-1, 0, 4), (0, -1, 3), (1, 3, -2), (3, 2, 1)]
This is fine if we only want to sort by the first value in each tuple, but what if we want to sort by the second or third value? Knowing how the built-in
sorted method works, we can use the key argument to define a function that will return the desired value (see How to Sort Python Dictionaries by Key or Value for some background on
sorted). Here’s how it would look for sorting with the 2nd value in each tuple:
>>> def sortkey(tup): ... return tup >>> sorted(tups, key=sortkey) [(0, -1, 3), (-1, 0, 4), (3, 2, 1), (1, 3, -2), (-2, 6, -5)]
This works perfectly, but we’ve used up extra space/lines (if in a script file), and extra memory for a one-statement function that only helps to sort our list. If using a different language, we might have no choice but to do this (or worse), but fortunately we have the
lambda function construct :-). With it we can define the same function in a simpler form:
# Returns a function >>> lambda tup: tup <function <lambda> at 0x02BD1230>
In the case of simplest we assigned the lambda function returned by the
lambda construct/statement to a value, but the power of the lambda construct is we don’t have to do that. Instead we can simply use the statement directly in
sorted for the key:
>>> sorted(tups, key=lambda tup: tup) [(0, -1, 3), (-1, 0, 4), (3, 2, 1), (1, 3, -2), (-2, 6, -5)]
It works the same way as with
sortkey, but by using this form the process is simpler and saves lines and memory!
This is the power of
lambda functions and their construct, but the best part is it will also work for any part of your script that needs such a function. That includes the built-in sorting/iterating functions (e.g.
filter), class methods such as
re.sub (with the
repl argument as a function), instance methods (as with
list.sort), callback functions for
Tkinter widgets, etc. So don’t hesitate to put
lambda functions to work and explore all that they are capable of doing!