Post by Hunter JozwiakHello,
I am not sure exactly why there would be a practical use for a lambda
function, other than the fact that you can make one-liner functions that
take parameters in to a variable. Or at least that is how things look when
they are written. Can I have some demystification?
To understand why lambda is useful will require a bit of background. So
let me start at the beginning.
The first thing you have to understand is that in modern languages like
Python, functions are not just things that operate on values, but they
are values themselves. So you can have a function which returns a new
function as its result. Here is a simple example:
py> def make_adder(n):
... def adder(x):
... return x + n
... return adder
...
py> add_one = make_adder(1)
py> add_one(100)
101
py> add_five = make_adder(5)
py> add_five(100)
105
"make_adder" is a function which takes an argument, n, and returns a new
function which takes one argument and returns that value plus the
earlier value "n". So make_adder(1) builds a function that adds 1 to its
argument, and make_adder(2) builds a function that adds 5 to its
argument.
Functions can not merely return functions, they can also take them as an
argument. Here's a simple example:
py> def add(a, b): # Function that adds two values.
... return a + b
...
py> def times(a, b): # Function that multiplies two values.
... return a*b
...
py> def builder(func):
... def op3(x):
... return func(x, 3)
... return op3
...
py> add_three = builder(add)
py> add_three(5)
8
py> times_three = builder(times)
py> times_three(5)
15
Now, those two examples themselves aren't terribly useful, it isn't very
often that you need a whole bunch of functions:
add_one
add_two
add_three
etc. But the ability to manipulate functions as arguments itself is
useful. For example, suppose you have a set of strings, and you need to
find out how long they all are:
py> strings = ["cat", "dog", "cheese", "aardvark", "elephant", "hamburger"]
py> lengths = []
py> for s in strings:
... lengths.append(len(s))
...
py> print lengths
[3, 3, 6, 8, 8, 9]
Having to build up a list yourself is a bit tedious, but there's another
way:
py> print map(len, strings) # Python 2 version.
[3, 3, 6, 8, 8, 9]
The "map" function takes a function (in this case, len) and applies it
to each item in strings, consolidating the results. The Python 3 version
is a little different, but the basic concept remains the same.
Suppose we had a list of numbers, and we wanted to create a new list
with each number doubled and then one added. We could do this:
py> def double_and_add_one(x):
... return 2*x + 1
...
py> map(double_and_add_one, [2, 3, 4, 5])
[5, 7, 9, 11]
but it seems a bit wasteful to have that function "double_and_add_one"
floating around in our program after we've used it, doing nothing
useful. It has a name and everything.
Python lets us create an unnamed function, right there in the expression
where it is being used. Once used, the interpreter can delete the
function and reclaim its memory. To do this, we use lambda:
py> map(lambda x: 2*x+1, [2, 3, 4, 5])
[5, 7, 9, 11]
If you have a function that looks like this:
def FUNCTION(args):
return EXPRESSION
that can be written using the lambda syntax:
lambda args: EXPRESSION
dropped right in the place where you are planning to use it, instead of
having to pre-define it using "def".
That makes lambda especially convenient for callback functions. For
example, many GUI toolkits let you set callbacks. Suppose you create a
button using some toolkit, like this, say:
save_button = Button("save", style="round")
What does the button do? So far, nothing: you can click on it, and
nothing happens. To give the button an action, you have to give it a
callback function. A callback is a function that the button will call
when you click on it:
def save(thebtn):
# whatever code you need to save the document
save_button = Button("save", style="round", callback=save)
Sometimes callbacks are particularly short and simple. Suppose you are
programming a calculator, and you have ten buttons 0...9 which all do
precisely the same thing: they add their own name to the calculator
display:
for num in range(0, 10):
btn = Button(str(num), style="rectangle",
callback = lambda thebtn: display.add(thebtn.name)
)
Much better than having to pre-define ten functions and add them to each
of the buttons.
These functions are called "anonymous functions", because unlike
functions created with "def", they don't have a name. Well, technically
they do, but they're all the same name:
py> (lambda x: x+1).__name__
'<lambda>'
which is only used for display, say, if there is an error. What makes
anonymous functions especially useful in languages other than Python is
that they are created at runtime, not compile-time, so they can include
information that is only known when the program runs. They are also
expressions, not statements, so you can use them wherever you might use
some other expression:
things = [123, "something", lambda x: x+1, {}, None]
You can't imbed a "def" inside a list, you have to define the function
first (giving it a name), then put it in the list:
things = [123, "something"]
def add_one(x):
return x + 1
things.append(add_one)
things.append({})
things.append(None)
So lambda is useful for writing small, simple, use-once and throw-away
functions.
There are two things to remember about lambda:
- Functions that you create with lambda are exactly the same as those
you create with def (apart from the lack of a name). def and lambda
don't create two different kinds of function, they are the same kind of
function. Only the syntax (and name) is different.
- lambda syntax is restricted to a single expression. So you can't
write:
lambda x: y = []
y.append(x)
return y
that will give a syntax error.
Any further questions, feel free to ask.
--
Steve
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor