On Dec 21, 10:36 pm, pbreit <pbreitenb...@gmail.com> wrote:
> I see lambda used quite a bit and don't totally understand the concept. Is
> there a simple rule to follow to know when it is necessary to use?

Code A:

f = lambda x,y: x + y

Code B:

def f(x,y):
    return x + y

If you can remember that Code A is *exactly* equivalent to Code B, you
will have no problem with lambda.   The differences between using def
to create a function, or lambda to create a function are the
following:

1) lambda is useful when creating inline functions for which no name
is necessary.  A very commonly-cited example is as a  comparison
function for the sort method:

my_list.sort(cmp=lambda a,b: a.age > b.age)

This "feels" more immediate and explicit than this:

def compare_age(a,b):
    return a.age > b.age
my_list.sort(cmp=compare_age

2) lambda is limited to a single expression.  If you need the function
to contain multiple statements and expressions, you have to use the
def version.

3) Using "def" means having to come up with a name, which implies the
possibility of adding some small documentation hint for what the
function is supposed to do.  Lambda provides no such hint; however, in
the scenarios in which lambda is most frequently used, the meaning and
purpose of the lambda function is immediately obvious, as in the
"sort" example above.  So perhaps a guideline might be to prefer "def"
when the purpose of the lambda function might not be immediately
obvious from the usage, and the name given to a "def" function would
be useful.

4) Python's scoping rules can catch out novice programmers very easily
with lambdas.  The typical example is a list comprehension in which a
list of functions is built:

my_list_of_functions = [lambda x : x + i for i in range(10)]

You think you're getting a list of 10 functions that will each add a
different amount (i.e. whatever "i" was at the time of each lambda
function declaration) to the function's input, "x", but in reality,
all functions will be identical, because the lambda captures the
location of the variable i, NOT its contents.  The exact same thing
would happen with def, except that def can't be used inline in this
way.  With "def", the code would be written so:

my_list_of_functions=[]
for i in range(10):
    def f(x):
        return x + i
    my_list_of_functions.append(f)

The exact same problem occurs as with lambda, but now of course it is
obvious that the location of i will be enclosed in the functions, and
therefore the desired effect will not be achieved.

* * *

FWIW always use functions to make closures, then the scoping is always
right:

def g(i):
    def f(x):
        return x + i
    return f
my_list_of_functions = [g(i) for i in range(10)]

I wrote up a fair bit on def and lambda in the web2py book, focusing
specifically on these kinds of scoping issues, and I wouldn't mind
feedback about anything that is unclear:

http://web2py.com/book/default/chapter/02#def...return

Reply via email to