[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

Re: Using lambda [was Re: Article of interest: Python pros/cons for theenterprise]

Terry Reedy

2/25/2008 2:13:00 AM


"Steven D'Aprano" <steve@REMOVE-THIS-cybersource.com.au> wrote in message
news:13s26luietu512c@corp.supernews.com...
| On Sat, 23 Feb 2008 19:35:30 -0800, Jeff Schwab wrote:
|
| > Every time somebody uses
| > lambda here, they seem to get a bunch "why are you using lambda?"
| > responses.

I think you are overgeneralizing ;-)
I use 'em.

| Not from me.
|
| I even use "named anonymous functions" *cough* by assigning lambda
| functions to names:
|
| foo = lambda x: x+1

Even though I consider the above to be clearly inferior to

def foo(x): return x+1

since the latter names the function 'foo' instead of the generic
'<lambda>'.
The only other situation in which I would critisize lambda usage are
multi-line (or super-long-line) monstrousities that are not intentionally
'obfuscated Python'.

tjr





5 Answers

Steven D'Aprano

2/25/2008 2:33:00 PM

0

On Sun, 24 Feb 2008 21:13:08 -0500, Terry Reedy wrote:

> | I even use "named anonymous functions" *cough* by assigning lambda |
> functions to names:
> |
> | foo = lambda x: x+1
>
> Even though I consider the above to be clearly inferior to
>
> def foo(x): return x+1
>
> since the latter names the function 'foo' instead of the generic
> '<lambda>'.

Absolutely. If foo() was a function that the user would see, I would
certainly use the def form to create it.

But in a situation like this:


def parrot(x, y, z, func=None):
if func is None:
func = lambda x: x+1
return func(x+y+z)


I don't see any advantage to writing it as:

def parrot(x, y, z, func=None):
if func is None:
def func(x): return x+1
return func(x+y+z)



--
Steven

Duncan Booth

2/25/2008 3:12:00 PM

0

Steven D'Aprano <steve@REMOVE-THIS-cybersource.com.au> wrote:

> On Sun, 24 Feb 2008 21:13:08 -0500, Terry Reedy wrote:
>
>> | I even use "named anonymous functions" *cough* by assigning lambda
|
>> functions to names:
>> |
>> | foo = lambda x: x+1
>>
>> Even though I consider the above to be clearly inferior to
>>
>> def foo(x): return x+1
>>
>> since the latter names the function 'foo' instead of the generic
>> '<lambda>'.
>
> Absolutely. If foo() was a function that the user would see, I would
> certainly use the def form to create it.
>
> But in a situation like this:
>
>
> def parrot(x, y, z, func=None):
> if func is None:
> func = lambda x: x+1
> return func(x+y+z)
>
>
> I don't see any advantage to writing it as:
>
> def parrot(x, y, z, func=None):
> if func is None:
> def func(x): return x+1
> return func(x+y+z)
>
>
>
I take it you never feel the need to inspect tracebacks, nor insert a
breakpoint or print statement at an arbitrary point in the code.

Granted none of those may apply in this particular simple case, but if
you pass functions/lambdas around a lot it can be frustrating when you
get an error such as:

TypeError: <lambda>() takes exactly 2 arguments (1 given)

and the traceback only tells you which line generated the TypeError, not
which lambda was involved. On the other hand:

TypeError: parrot_func() takes exactly 2 arguments (1 given)

while it might not identify the function uniquely in all situations at
least tells you something useful about the function being called.

Steven D'Aprano

2/25/2008 3:35:00 PM

0

On Mon, 25 Feb 2008 15:12:23 +0000, Duncan Booth wrote:

> I take it you never feel the need to inspect tracebacks, nor insert a
> breakpoint or print statement at an arbitrary point in the code.


Nah, my code is always perfect, first time, every time.

*wink*

> Granted none of those may apply in this particular simple case,

This sort of simple case is the one where I would use lambda.


> but if
> you pass functions/lambdas around a lot it can be frustrating when you
> get an error such as:
>
> TypeError: <lambda>() takes exactly 2 arguments (1 given)
>
> and the traceback only tells you which line generated the TypeError, not
> which lambda was involved. On the other hand:

In the simple cases I'm talking about, there is only one lambda in scope
at a time. If that were not the case, I'd use def.


> TypeError: parrot_func() takes exactly 2 arguments (1 given)
>
> while it might not identify the function uniquely in all situations at
> least tells you something useful about the function being called.

Sure. For a more complicated case where I'm passing the function around a
lot, def is the way to go. Likewise if the function is complex, I'd use
def instead of trying to cram the whole algorithm into a single
expression for lambda.

I'm not saying that I never use nested def, only that I sometimes assign
lambdas to names. And why not? A lambda function is a first class object
like everything else :)


--
Steven

Duncan Booth

2/25/2008 4:03:00 PM

0

Steven D'Aprano <steve@REMOVE-THIS-cybersource.com.au> wrote:

>> but if
>> you pass functions/lambdas around a lot it can be frustrating when you
>> get an error such as:
>>
>> TypeError: <lambda>() takes exactly 2 arguments (1 given)
>>
>> and the traceback only tells you which line generated the TypeError, not
>> which lambda was involved. On the other hand:
>
> In the simple cases I'm talking about, there is only one lambda in scope
> at a time. If that were not the case, I'd use def.
>
In the fictional example you gave there are potentially two lambdas: the
one passed in or the default one.

I use lambda quite often myself, but I do feel that if you do have a name
for the function then you might as well tell the function what it's called.
It probably won't matter, but it doesn't hurt you (2 extra characters to
type), and it might just save you grief further down the line. Each to his
own though.

Terry Reedy

2/25/2008 8:43:00 PM

0


"Steven D'Aprano" <steve@REMOVE-THIS-cybersource.com.au> wrote in message
news:13s5kclk4maa584@corp.supernews.com...
| On Sun, 24 Feb 2008 21:13:08 -0500, Terry Reedy wrote:
|
| > | I even use "named anonymous functions" *cough* by assigning lambda |
| > functions to names:
| > |
| > | foo = lambda x: x+1
| >
| > Even though I consider the above to be clearly inferior to
| >
| > def foo(x): return x+1
| >
| > since the latter names the function 'foo' instead of the generic
| > '<lambda>'.
|
| Absolutely. If foo() was a function that the user would see, I would
| certainly use the def form to create it.
|
| But in a situation like this:
|
|
| def parrot(x, y, z, func=None):
| if func is None:
| func = lambda x: x+1
| return func(x+y+z)

Since functions are constants with respect to code attribute, you might as
well condense that to

def parrot(x,y,z, func = lambda xyz: xyz+1):
return func(x+y+z)

Then you can claim some actual space saving.

| I don't see any advantage to writing it as:
|
| def parrot(x, y, z, func=None):
| if func is None:
| def func(x): return x+1
| return func(x+y+z)

Good habit?
Don't mislead the newbies ;-?

tjr