Velocity Reviews > explain this function to me, lambda confusion

# explain this function to me, lambda confusion

globalrev
Guest
Posts: n/a

 05-07-2008
i have a rough understanding of lambda but so far only have found use
for it once(in tkinter when passing lambda as an argument i could
circumvent some tricky stuff).
what is the point of the following function?

return lambda x,inc=n: x+inc

if i do addn(5) it returns

return lambda x,inc=n: x+inc

<function <lambda> at 0x01D81830>

ok? so what do i write to make it actually do something. and is the
inc=n necessary i cant do x+n?

globalrev
Guest
Posts: n/a

 05-07-2008
and what si the diffrence here:

g = lambda x=5*x
g = lambda x*x

the first was a mistake to write but it worked
and the x=5 seems to be completely ignored. why? it has no effect at
all?

globalrev
Guest
Posts: n/a

 05-07-2008
On 7 Maj, 23:47, globalrev <(E-Mail Removed)> wrote:
> and what si the diffrence here:
>
> g = lambda x=5*x
> g = lambda x*x
>
> the first was a mistake to write but it worked
> and the x=5 seems to be completely ignored. why? it has no effect at
> all?

ah wait now i see it has a default kind of then. g() returns 25 while
g( returns 64.

bruno.desthuilliers@gmail.com
Guest
Posts: n/a

 05-07-2008
On 7 mai, 23:38, globalrev <(E-Mail Removed)> wrote:
> i have a rough understanding of lambda but so far only have found use
> for it once(in tkinter when passing lambda as an argument i could
> circumvent some tricky stuff).
> what is the point of the following function?
>
> return lambda x,inc=n: x+inc

It returns a function that accept one argument and return the result
of the addition of this argument with the argument passed to addn.

FWIW, Python's lambda is just a shortcut to create a very simple
function, and the above code is canonically written as:

return n + x

> if i do addn(5) it returns
>

(snip)

> <function <lambda> at 0x01D81830>
>
> ok? so what do i write to make it actually do something.

=> 6
=> 7

=> 43

> and is the
> inc=n necessary i cant do x+n?

In this case, it's not. This version does exactly the same thing
AFAICT:

return lambda x: x+n

Gabriel Genellina
Guest
Posts: n/a

 05-07-2008
En Wed, 07 May 2008 18:38:15 -0300, globalrev <(E-Mail Removed)>
escribió:

> i have a rough understanding of lambda but so far only have found use
> for it once(in tkinter when passing lambda as an argument i could
> circumvent some tricky stuff).
> what is the point of the following function?
>
> return lambda x,inc=n: x+inc

lambda is just a shortcut for defining a function without a name.
The above code is the same as:

def inner(x, inc=n):
return x+inc
return inner

It should be clear now that addn returns a function. addn is a "function
factory": builds functions by request. You ask it "give me a function that

> if i do addn(5) it returns
>

> <function <lambda> at 0x01D81830>

If you try the other version, you would get:

<function inner at 0x00A3B970>

It's the same thing, except that lambda has no name.

> ok? so what do i write to make it actually do something.

-> 8

> and is the
> inc=n necessary i cant do x+n?

Yes, you can, but there is a subtle difference that's hard to explain, and
in this case it's absolutely irrelevant. Using inc=n "does the right
thing" as it's a bit more efficient too.

--
Gabriel Genellina

andrej.panjkov@climatechange.qld.gov.au
Guest
Posts: n/a

 05-08-2008
On May 8, 7:38 am, globalrev <(E-Mail Removed)> wrote:
> i have a rough understanding of lambda but so far only have found use
> for it once(in tkinter when passing lambda as an argument i could
> circumvent some tricky stuff).
> what is the point of the following function?
>
> return lambda x,inc=n: x+inc
>
> if i do addn(5) it returns
>

>
> return lambda x,inc=n: x+inc
>

>
> <function <lambda> at 0x01D81830>
>
> ok? so what do i write to make it actually do something. and is the
> inc=n necessary i cant do x+n?

Here are some notes I have written for our local wiki on lambdas in
python. I hope you will find them illuminating, and I would welcome
any suggestions for improving them.

I have just cut and pasted from our wiki, so the fancy formatting has
been lost.

-----

Python lambdas.

The on-line documentation for python lambdas is not very illuminating.
Here¡¯s my take and my first simple examples.

I would describe a lambda as a parameterised function template. If you
dig, the docs call lambdas anonymous functions not bound to a name.
There is a bit of resemblance to C macros.

Here is a simple lambda that implements an exclusive or:

>>> def XOR(x,y) :
>>> return lambda : ( ( x ) and not ( y ) ) or ( not ( x ) and ( y ) )

(Because of the resemblance to C macros, I have been cautious and
written the lambda with lots of parentheses.)

To use this in later code, we define instances of the lambda with
specific function arguments.

>>> topping = XOR( cream, icecream)
>>> sauce = XOR( tomato, BBQ )

We now have two ¡°functions¡±, topping() and sauce() which we can use
later to test flags.

>>> cream = True
>>> icecream = False
>>> print topping()

True

So in the definition of the XOR lambda, think of x and y as the
parameters of the function template, and XOR as the function name
placeholder.

By putting in specific objects for the parameters (here the boolean
variables cream and icecream for example), we produce a specific
instance of the lambda, topping() which looks like a function with no
arguments.

If we use different objects for the parameters (say tomato and BBQ)
then we get a different function, sauce.

Here is another simple lambda, (template) to set up three new

#--# Lambda function to check that a flag is only on when the other
two are off. #--#
def TFF(x,y,z) :
return lambda : ( ( x ) and not ( y ) and not ( z ) )

options.DeleteAction )
options.ReplaceAction )
options.DeleteAction )

if( not (DeleteOnly() or AddOnly() or ReplaceOnly() ) ):
print "Error: Exactly one of [ --add | --replace | --delete ]
allowed. "
parser.print_help()
exit

The examples above give function instances that have no arguments,
once the parameters of the lambda are chosen.

For a function template with arguments and parameters, we add the
arguments on the 2nd line. Parameters are in the first line.

The Gaussian distribution is exp(-(x-¥ì)©÷/ 2¥ò©÷ ) / ¡î(4 ¥ð¥ò). While we
can think of this as a function of three variables, we normally view
it as a family of functions of a single variable x, parameterised by ¥ì
and ¥ò. Selecting fixed values for ¥ì and ¥ò gives us a single
distribution for x.

>>> import math
>>> def Gaussian( mu, sigma ) :

... return lambda x : math.exp( - (x-mu)**2 / 2 /sigma**2 ) /
math.sqrt (2 * math.pi *sigma **2 )
...
>>>

and here are some instances:

>>> Normal = Gaussian (0, 1)
>>> HeightDistrib = (170, 20)

which we later use as

>>> y = Normal( 0.5 )

0.35206532676429952
>>> x = 192
>>> HeightDistrib(x)

0.0073381331586869951

I recommend defining the instances of the lambda right after the
lambda. If you define it in code far removed from the definition of
the lambda, it looks like an assignment, so comment it.

andrej.panjkov@climatechange.qld.gov.au
Guest
Posts: n/a

 05-08-2008
On May 8, 10:34 am, (E-Mail Removed) wrote:
>
> >>> HeightDistrib = (170, 20)

>

That should be
> >>> HeightDistrib = Gaussian(170, 20)

Terry Reedy
Guest
Posts: n/a

 05-08-2008

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...

| On May 8, 7:38 am, globalrev <(E-Mail Removed)> wrote:
| I would describe a lambda as a parameterised function template. If you
| dig, the docs call lambdas anonymous functions not bound to a name.

A lambda expression is an abbreviation of a simple def statement:
f = lambda args: expression
def f(args): return expression
have exactly the same effect except that f.func_name will be the less
useful '<lambda>' instead of the more useful 'f'.

| There is a bit of resemblance to C macros.

Macros in C (and, I believe, some places elsewhere) are text-replacement
templates. They are markedly different from function statements. C macros
do not create C functions. Python lambda expression do create Python
function objects. Since C macros are statements, not expressions, and are
introduced by #define, similar to def, one could argue than Python def
statements are more similar to C macros.

| Here is a simple lambda that implements an exclusive or:
|
| >>> def XOR(x,y) :
| >>> return lambda : ( ( x ) and not ( y ) ) or ( not ( x ) and ( y ) )

def XORY(x,y):
def _xory(): x and not y or not x and y
return _xory

has the same effect. Because lambda expressions define functions, not
macros, there is no need for the protective parentheses that macros need.

Here is another simple lambda, (template) to set up three new
| functions AddOnly, DeleteOnly, and ReplaceOnly.
|
| #--# Lambda function to check that a flag is only on when the other
| two are off. #--#
| def TFF(x,y,z) :
| return lambda : ( ( x ) and not ( y ) and not ( z ) )

def TFF(x,y,z):
def _tff(x,y,z): return ( ( x ) and not ( y ) and not ( z ) )
return _tff

Same result (except for a real name in tracebacks), same usage.

| >>> import math
| >>> def Gaussian( mu, sigma ) :
| ... return lambda x : math.exp( - (x-mu)**2 / 2 /sigma**2 ) /
| math.sqrt (2 * math.pi *sigma **2 )

def Gaussian(mu, sigma):
def _gaussian(x): return math.exp( - (x-mu)**2 / 2 /sigma**2 ) /
math.sqrt (2 * math.pi *sigma **2 )
return _gaussian

Again, giving the returned function a name will help a bit if it raises an
exception, which is definitely possible here.

Lambda expressions are an occasional convienience, not a requirement.
Anyone who is confused by what they do should use an equivalent def

Terry Jan Reedy

andrej.panjkov@climatechange.qld.gov.au
Guest
Posts: n/a

 05-09-2008
On May 8, 6:11 pm, Duncan Booth <(E-Mail Removed)> wrote:

>
> No, no, no, no, no!
>

Geez. Go easy.

> You have got it entirely wrong here. Your XOR function simply returns a
> function which gives you the result of xoring the parameters AT THE TIME
> WHEN YOU ORIGINALLY CREATED IT. I'm guessing that you had already set
> cream and icecream (otherwise the call to XOR would have thrown an
> exception) and at leas one was true. Try setting them both False at the
> beginning:
>
> >>> cream = False
> >>> icecream = False
> >>> topping = XOR( cream, icecream)
> >>> cream = True
> >>> icecream = False
> >>> print topping()

>
> False
>

Ok. I understand this better now. I did say I found the documentation
rather terse on this.

> Using a lambda was a completely pointless exercise here, you could have
> just returned the result directly:

If I try out a new language, I try to exercise those parts of the
language that are new to me. Now I saw lambdas, an interesting
structure I hadn't seen before. So I tried them out. I get to learn a
little at the same time as scripting. That was the "point". I only
get to optimise my use of a language by trying out various corners of
it.

> def TFF(x,y,z) :
> return x and not y and not z
>
> options.DeleteAction )
> DeleteOnly = TFF( options.DeleteAction, options.AddAction,
> options.ReplaceAction )
> ReplaceOnly = TFF( options.ReplaceAction, options.AddAction,
> options.DeleteAction )
>
> if not (DeleteOnly or AddOnly or ReplaceOnly):
> print "Error: Exactly one of [ --add | --replace | --delete ]
> allowed. "
> parser.print_help()
> exit
>
> which boils down to:
>
> if (options.AddAction + options.ReplaceAction +
> options.DeleteAction) != 1:
> print "Error: ..."

Indeed, there are many ways this could be done. Some are more
concise, some are more efficient. As I said, I did it the way I did
it to try out lambdas. Your way achieves the result, rather elegantly
I think, but teaches me nothing about using lambdas.

Pardon my tetchiness, but it is a little hard to receive such blunt
and inflexible replies to my posts.

Both the responses offer lambda free alternatives. That's fine, and
given the terse documentation and problems that I had understanding
them, I would agree. So what applications are lambdas suited to? I
think the parameterised function model is one.
What else?

Gabriel Genellina
Guest
Posts: n/a

 05-09-2008
En Thu, 08 May 2008 22:57:03 -0300,
<(E-Mail Removed)> escribió:

> On May 8, 6:11 pm, Duncan Booth <(E-Mail Removed)> wrote:
>
>> No, no, no, no, no!

> Geez. Go easy.
>> You have got it entirely wrong here. Your XOR function simply

[...]
> Pardon my tetchiness, but it is a little hard to receive such blunt
> and inflexible replies to my posts.

Don't take it so seriously. I would have written a reply in the same tone.
Weeds must be uprooted early

> Both the responses offer lambda free alternatives. That's fine, and
> given the terse documentation and problems that I had understanding
> them, I would agree. So what applications are lambdas suited to? I
> think the parameterised function model is one.
> What else?

It should be clear now that lambda is just a shortcut for defining a
normal function using "def", except it has no name, and it can handle
expressions only (no statements).
So you never *need* a lambda. But in a few cases they're useful:

- Most GUIs are event-driven, and let you bind a function (or any other
callable object) to be executed when certain event happens (by example,
when certain button is pressed, or a menu item is selected). Usually an
instance method is used: Button("Total", onclick=self.calculate_total).
Suppose you're developing a calculator; the ten buttons labeled '0' to '9'
should inserte the corresponding digit. To do that, you should write ten
functions insert_digit_0 to insert_digit_9 (and they would be
one-line-functions: insert_digit('0') ... insert_digit('9')). Too boring
The usual idiom is something like this:
Button("0", onclick=lambda: self.insert_digit('0'))
Button("5", onclick=lambda: self.insert_digit('5'))

- To write an expression that is to be evaluated lazily (perhaps only if
certain other conditions are met). Older Python versions didn't have a
conditional expression like C's ternary operator, and one possible way
to emulate it is this:

def iif(cond, if_true, if_false):
if cond:
return if_true()
else:
return if_false()

iff(x!=2, lambda: 1/(x-2), lambda: 100)

You can't write iff(x!=2, 1/(x-2), 100) because arguments are evaluated
before the function is called, and with x=2 you get an error.

--
Gabriel Genellina