On Tue, Oct 27, 2015 at 09:04:45PM -0400, Hunter Jozwiak wrote: > Hello, > > 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 - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor