lambda_hrs = lambda x: (x/60,x%60)
> Dear All,
>
> Can't a lambda uses the input parameter more then once in the lambda
> body?
> eg:
> lambda x : print x/60,x%60
>
> I tried with def and it works but got syntax error with lambda. Below
> is an interactive sample:
Lambda evaluates a single *expression* and returns the result. As print
is a statement it does not qualify (and would provide nothing to return
even if it did). So just use a def. It is constantly pointed out on
this list that the lambda provides no extra expressive power, it is
merely a shortcut and, as you just found out, a rather restrictive one
at that.
See the reference manual entry:
http://www.python.org/doc/2.4.2/ref/lambdas.html
As for your next question,
lambda x : x/60,x%60
is parsed as
(lambda x: x/60), x%60
That is, the scope of the lambda (and its x) are finished by the comma.
Perhaps being more explicit about the returned tuple would produce what
you want.
lambda x : (x/60,x%60)
Gary Herron
>
> linuxlah@algorhythm ~ $ python
> Python 2.4.2 (#1, Nov 18 2005, 19:32:15)
> [GCC 3.3.6 (Gentoo 3.3.6, ssp-3.3.6-1.0, pie-8.7.8)] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
> >>> def func_hrs(x): print x/60,x%60
> ...
> >>> func_hrs(400)
> 6 40
> >>> lambda_hrs = lambda x : print x/60,x%60
> File "<stdin>", line 1
> lambda_hrs = lambda x : print x/60,x%60
> ^
> SyntaxError: invalid syntax
> >>>
>
> My main concern is how can I do this in lambda?
>
>
>
> --
> And whoever does an atom's weight of evil will see it.
> Try
>
> lambda_hrs = lambda x: (x/60,x%60)
Or
#v+
lambda_hrs = lambda x: divmod(x, 60)
#v-
Cheers,
--
Klaus Alexander Seistrup
PNX · http://pnx.dk/
or use sys.stdout.write in your lambda:
import sys
lambda x : sys.stdout.write("%d %d\n" % (x/60, x%60))
> It is constantly pointed out on
> this list that the lambda provides no extra expressive power,
They do, when one need a very trivial callable for callbacks - which is
probably the main (if not the only) use case.
> it is
> merely a shortcut and, as you just found out, a rather restrictive one
> at that.
Of course.
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'on...@xiludom.gro'.split('@')])"
>Gary Herron wrote:
>> Mohammad Jeffry wrote:
>>
>>> Dear All,
>>>
>>> Can't a lambda uses the input parameter more then once in the lambda
>>> body?
>>> eg:
>>> lambda x : print x/60,x%60
>>>
>>> I tried with def and it works but got syntax error with lambda. Below
>>> is an interactive sample:
>>
>>
>> Lambda evaluates a single *expression* and returns the result. As print
>> is a statement it does not qualify (and would provide nothing to return
>> even if it did). So just use a def.
>
>or use sys.stdout.write in your lambda:
>import sys
>lambda x : sys.stdout.write("%d %d\n" % (x/60, x%60))
>
>> It is constantly pointed out on
>> this list that the lambda provides no extra expressive power,
>
>They do, when one need a very trivial callable for callbacks - which is
>probably the main (if not the only) use case.
>
>> it is
>> merely a shortcut and, as you just found out, a rather restrictive one
>> at that.
>
>Of course.
>
If you think lambda is restrictive, you can use dumbda:
>>> def dumbda(src):
... d = {}
... exec src in d
... for k,v in d.items():
... if callable(v): return v
... else:
... raise ValueError('dumbda produced no callable from:\n%s'%src)
...
>>> f = dumbda("def foo(x): print 'foo(%r)'%x")
>>> f('hello foo')
foo('hello foo')
I'd prefer an "anonymous def" though ;-)
Regards,
Bengt Richter
No, it is not merely a shortcut. It often allows one to avoid
polluting
the namespace with a completely superfluous function name, thus
reducing code smell. It can also avoid a multi-line function defintion
which often pushes other relevant code off the current page and
out of view, and thus lambda can increase program readability.
> and, as you just found out, a rather restrictive one
> at that.
In part because Python's designers failed to make "print" a function
or provide an if-then-else expression.
> --snip--
Which can also be done by using inner functions.
> It can also avoid a multi-line function defintion which often pushes
> other relevant code off the current page and out of view, and thus
> lambda can increase program readability.
def somefunc(x): return x*5
How is that a multi-line function definition?
Sybren
--
The problem with the world is stupidity. Not saying there should be a
capital punishment for stupidity, but why don't we just take the
safety labels off of everything and let the problem solve itself?
Frank Zappa
> def somefunc(x): return x*5
>
> How is that a multi-line function definition?
but that's namespace pollution! if you do this, nobody will never ever be
able to use the name somefunc again! won't somebody please think about
the children!
</F>
Inner functions with no names?
> > It can also avoid a multi-line function defintion which often pushes
> > other relevant code off the current page and out of view, and thus
> > lambda can increase program readability.
> def somefunc(x): return x*5
> How is that a multi-line function definition?
def mult_by_five():
def somefunc(x): return x*5
return somefunc
is multi-line, as opposed to:
def mult_by_five(): return lambda x: x*5
For future reference, "polluting the namespace" is doing something
stupid like
from cgi import *
which will essentially dump a huge number of unknown names, some of
which you may have decided to use for yourself already, into the local
namespace.
Even without shouting "Namespaces are a honking good idea, let's do more
of those", I should just like to make a small plea for everyone to
remember that namespaces are there specifically to allow us to name things!
>
>> and, as you just found out, a rather restrictive one
>>at that.
>
>
> In part because Python's designers failed to make "print" a function
> or provide an if-then-else expression.
>
But they did provide file.write(), which while not perhaps as convenient
as print is quite easy to use. Though not as easy, I'll admit, as
spouting on comp.lang.py ;-). But I just *know* that there'll be as many
complaints about the absence of the print statement from Python 3 as
there are about its presence (as a statement rather than a function) in
Python 2.
As for the if-then-else expression, I suspect I'll use the ternary
operator very infrequently, as I don't myself see many readability
advantages to it. Its major value to me will be cutting down the cruft
we see in this newsgroup.
Paul Rubin wrote:
> Sybren Stuvel <sybr...@YOURthirdtower.com.imagination> writes:
>
>>>No, it is not merely a shortcut. It often allows one to avoid
>>>polluting the namespace with a completely superfluous function name,
>>>thus reducing code smell.
>>
>>Which can also be done by using inner functions.
>
>
> Inner functions with no names?
>
Well, you could give them all the same name if you define them just
before they're used :-)
>
>>>It can also avoid a multi-line function defintion which often pushes
>>>other relevant code off the current page and out of view, and thus
>>>lambda can increase program readability.
>>
>>def somefunc(x): return x*5
>>How is that a multi-line function definition?
>
>
> def mult_by_five():
> def somefunc(x): return x*5
> return somefunc
>
> is multi-line, as opposed to:
>
> def mult_by_five(): return lambda x: x*5
Again I'm a little tired of suggestions that reducing things to one-line
form necessarily improves readbility. If your functions are so long that
it's important to add as few lines as possible to them you should fix
this by refactoring your code to avoid over-long functions.
regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/
Nor any less.
> Why use temporary variables when all you have to do is make your
> expressions three lines long to avoid "polluting the namespace"?
Indeed. I'd much rather say
x = a + b + (c * d) + e
than
temp1 = a + b
temp2 = c * d
temp3 = temp1 + temp2
x = temp3 + e
I don't understand why the critics of lambda don't understand that
having to use so many temp variables, for either numbers or functions,
can work against both concision and clarity.
> Even without shouting "Namespaces are a honking good idea, let's do
> more of those", I should just like to make a small plea for everyone
> to remember that namespaces are there specifically to allow us to name
> things!
Not everything needs a name.
For some people, the second form is clearer.
I dashed that last part off quickly, so I don't have a good reason.
Maybe to insert a debugging print temporarily?
def debug(x): print x
reduce(lambda x,y: (x+y, debug(x))[0], range(10))
I agree, if I were to name my function `shuffle', then I wouldn't be
able to name any of my intermediate functions `shuffle'! Oh the
humanity! Therefore I will instead use adhere to my 0 namespace
pollution policy and use this instead:
__nopollution_at__all_portion = range(50)
__nopollution_at__all_word = 'mint white chocolate chip'
if __name__ == '__main__':
print (lambda portion,word:(lambda x,word:[x.pop() for i in
range(len(word))]+x)((lambda x,word:[x.pop() for i in
range(len(word))]+x)((lambda x,word:[x.pop() for i in
range(len(word))]+x)((lambda x,word:[x.pop() for i in
range(len(word))]+x)(portion[:],word),word),word),word))(__nopollution_at__all_portion,__nopollution_at__all_word)
;-)
There's also
lambda x, y: sys.stdout.write('%s\n' % x) or x + y
But there is no suggestion that this should be the obligatory form.
--
Antoon Pardon
I think there is, for python. Not that I agree with it. The language
doesn't prevent you from using the short one-liner style but the idioms
prefer the line by line(and one single op/action per line) style.
Are you serious?!! You're saying idiomatic Python prefers
temp1 = a + b
temp2 = c * d
temp3 = temp1 + temp2
x = temp3 + e
to
x = a + b + (c * d) + e
???!!!
I don't think you look at the same Python code I do ;-).
That is odd, because I remember very well that at one time I was using
such a line by line approach and it was almost regarded as a bug.
The only difference of relevance between the above was that the last
line was a call, instead of an assignment.
The prime argument for why such a style was not done, was that it
kept all kinds of references to temporary results active, which
meant they couldn't be recycled by the garbage collector.
--
Antoon Pardon
Not for this particular example, but that is the impression I get, I
said the "form/style". Especially when we are talking about
reduce/map/filter vs explicit for loop.
The point I was trying to make (about namespace pollution, originally)
is that namespaces exist precisely so we can bind names to values. If a
program is properly composed then most names aren't that long-lived
anyway because they go out of scope at the end of the function call
during which their bindings are made.
One perhaps needs to be a little more careful with instance variables,
but again most *temporaries* are simply local to the method in which
they're called, they don't exist for the lifetime of the instance.
One shouldn't obsess about every little detail - Python is ultimately
for solving problems. I see plenty of code I wouldn't necessarily write
myself on this list, but as long as it solves the poster's problem and
doesn't contain any egregious errors I'm happy to let it by.
For the record, this includes uses of reduce, map and filter: I don't
naturally favour a functional style myself, but I can live quite happily
alongside those who do. The same will be true of the ternary x if y else
z construct when it arrives.
> One perhaps needs to be a little more careful with instance variables,
> but again most *temporaries* are simply local to the method in which
> they're called, they don't exist for the lifetime of the instance.
and more importantly, temporary variables can be reused. they're only
bound to a given object until you bind them to some other object. the
following is a perfectly good way to define a couple of callbacks:
def callback():
...
b1 = Button(master, command=callback)
def callback():
...
b2 = Button(master, command=callback)
def callback():
...
b3 = Button(master, command=callback)
(three callbacks, a single temporary name)
to refer to variables from the outer scope from inside a callback,
just use the variable. to refer to *values* from the outer scope,
use argument binding:
def callback(arg=value):
...
b3 = Button(master, command=callback)
since "def" is an executable statement, and the argument line is
part of the def statement, you can bind the same argument to
different values even for the same function, e.g.
for i in range(10):
def callback(button_index=i):
...
b = Button(master, command=callback)
this loop creates ten distinct function objects.
</F>
But this seems to defeat the main argument for removing lambda
and using def's instead.
One of the most repeated arguments against using lambda is that
no (meaningfull) name is associated with it, that can help
in tracking bugs in case of a traceback. But if you are
having a lot of functions with the same name you won't get
much usefull information either.
I also don't see such a style being advocated in other cases.
Sure I can write my code like this:
for i in xrange(10):
arg = 2 * i + 1
func(arg)
But nobody is suggestion this is how it should be and that
something is wrong with the following:
for i in xrange(10):
func(2 * i + 1)
I have seen a number of suggestion that may reduce the use
of lambda without having to use a def instead.
e.g.
fivefold = lambda x: x * 5
could be replace by:
fivefold = types.MethodType(operator.mul, 5)
There is also PEP 309 which introduces a partial class,
with the same kind of functionality. The above would
then become:
fivefold = partial(operator.mul, 5)
This should work from python 2.5, but a working implemantation
seems to be in the PEP, as well as a reference to the cookbook
with alternative implementations. Partial also seems to
be more general than MethodType.
I doubt this will eliminate the need of lambda but AFAIS
it reduces the need. An idea that may eliminate the need
totaly, would be the introduction of name parameters.
When you call a function with a name parameter, the expression
for the parameter isn't evaluated, but instead an evaluatable
form is created (something like a lambda), that is evaluated
each time the parameter is used. Since the most arguments
in favor of the lambda are the possibility to use an expression
as a parameter, this may be an acceptable alternative for
those who use lambda now
I don't know how well name parameters would fit in with the
rest of python though.
--
Antoon Pardon
If you use that as an inner function, it only "pollutes" the local
namespace of that function. How's that influencing the rest of the
world?
I think you need to turn your irony detector up a little - it looks like
hte gain is currently way too low :o)
Consider my detector tweaked ;-)
All joking aside, when I have names (temporary variables or scaffolding
functions) that I need to initialise a module or data structure, but then
outlive their usefulness, I del the name afterwards. Am I the only one? I
can't say I've seen anyone else doing that, and it feels icky to me (for
no reason I can put my finger on) -- what do others think?
--
Steven.
I don't do that. I tend to split up my code into pretty small
functions, so the temporary names I use have a small scope as is. I
don't see the need to add extra 'del' commands when the 'return' five
lines further down is going to do the same.
Well I don't do it, but it has bothered me. The direction I'm thinking
of right now is doing all such initialisation within an initialisation
function, all temporary variables or scaffolding functions, defined
in that function will disappear automatically when the function has
done its job.
--
Antoon Pardon
If anybody needs to break an expression with three short terms up into
individual temporary variables in order to understand it, then I suggest
they should re-think their career choice as a programmer.
Having said that, there are some expressions which are sufficiently
complex that they do need to be broken up into smaller pieces. In which
case, you *should* be naming the pieces, and not trying to shoe-horn them
into a one-liner.
--
Steven.
You must be some kind of Python neatnik! If I need the external
appearance of a module to be tidy I just use __all__.
I do that too sometimes. I think it's a Python weakness that you
can't declare a local var like in other languages, to go out of scope
at the end of the current block, e.g.:
if cond:
my x = 7 # make a new scope for x, goes out of scope at end of if
> I don't generally speaking see the point: unless the name is
> referencing something potentially large (like the results of a
> database query) and won't be going out of scope soon (which typically
> happens at the end of the current method or function) I just leave it
> to happen automatically. If it doesn't happen (because the name exists
> at module scope) thwn what the heck.
Well, that makes the code a little bit confusing. If you say
x = some_intermediate_result(...)
do_something_with (x)
do you know for sure whether x will be needed again? Are you sure you
didn't use the name x further up in the function for something that's
still needed?
This is one of the areas where there's tension between Python the
scripting language, that gains by saving a few keystrokes when
throwing together a quick hack, and Python the language for developing
long-lasting applications that have to be maintained by multiple people.
In Haskell you can even have temporary variables inside an expression:
x = y + y*y + 3 where y=5
sets x to 33. I believe (not absolutely sure) that the scope of y is
limited to that expression.
> Steve Holden <st...@holdenweb.com> writes:
>> > All joking aside, when I have names (temporary variables or
>> > scaffolding functions) that I need to initialise a module or data
>> > structure, but then outlive their usefulness, I del the name
>> > afterwards. Am I the only one? I can't say I've seen anyone else
>> > doing that, and it feels icky to me (for no reason I can put my
>> > finger on) -- what do others think?
> I do that too sometimes. I think it's a Python weakness that you
> can't declare a local var like in other languages, to go out of scope
> at the end of the current block, e.g.:
> if cond:
> my x = 7 # make a new scope for x, goes out of scope at end of if
For a dissenting opinion: I *like* Python's three-scope setup. The
last thing I want is to get into an if statement (or two) inside a for
statement inside a method definition inside a class definition and to
have to wonder if "x" is local to the if-suite (or the outer if-suite),
the for-suite, the method definition, the class definition, or the
module. And allowing multiple "x"'s in all these different scopes to
shadow each other just makes it worse.
IMO, if my suites, methods, classes, and modules are sufficiently large,
and their documentation and my text editor sufficiently weak, that I
can't figure out a "good" local name to use at any given point in the
code, or that I have to wonder which "x" I really want at that point, or
that I have to worry about creating a sub-suite (with no extra scoping)
and clobbering an important name, then I've already done something
enormously wrong.
> Well, that makes the code a little bit confusing. If you say
> x = some_intermediate_result(...)
> do_something_with (x)
> do you know for sure whether x will be needed again? Are you sure you
> didn't use the name x further up in the function for something that's
> still needed?
I never know for sure whether x will be needed again. But if the
function from which you took that snippet is large enough that there's
any question about it, then perhaps it's too large already. And if
there's a chance that x might be useful elsewhere, then I should have
called it something other than x (or immediately rename it as soon as I
start to think about using its contents again).
(Okay, now I sound like a curmudgeon, but I'm not. At least I don't
think I am. I'm just trying to present an alternate view, one in which
the issue of needing more scoping controls isn't an issue.)
Regards,
Dan
--
Dan Sommers
<http://www.tombstonezero.net/dan/>
> Steven D'Aprano enlightened us with:
>> All joking aside, when I have names (temporary variables or
>> scaffolding functions) that I need to initialise a module or data
>> structure, but then outlive their usefulness, I del the name
>> afterwards. Am I the only one?
>
> I don't do that. I tend to split up my code into pretty small
> functions, so the temporary names I use have a small scope as is. I
> don't see the need to add extra 'del' commands when the 'return' five
> lines further down is going to do the same.
But then you have all these small functions lying around in your module.
If you intend to use them multiple times, then obviously you should
keep them. But if they are intended to be used once, and once only, it
seems bad to leave them there tempting fate.
E.g. you have some code that uses a large lookup table. Rather than type
the lookup table in by hand, you write a function which creates all or
part of it. Once the lookup table is created, you shouldn't use that
function again -- at best it is just sitting around like a third wheel,
at worst it might have side-effects you don't want. So I del the function.
The logic seems impeccable to me, and yet somehow deleting them after they
are used feels ... not so much wrong, as just ... worthy of a
head-scratching.
--
Steven.
I'd prefer to check the lookup table, and raise a descriptive
exception if it already exists. That'll be a lot clearer than the
error that a function doesn't extst, while it is clearly defined in
the source.
I've no objection to the practice when it makes a difference, but ask
yourself how many bytes you are saving by allowing the code for that
function to be collected.
Having said this, neither do I have any objection to your continuing to
anally tidy up your namespace, but then I'm a slob whose partner is a
neat freak, so I'm well used to accommodating the unnecessary.
>
>>I don't generally speaking see the point: unless the name is
>>referencing something potentially large (like the results of a
>>database query) and won't be going out of scope soon (which typically
>>happens at the end of the current method or function) I just leave it
>>to happen automatically. If it doesn't happen (because the name exists
>>at module scope) thwn what the heck.
>
>
> Well, that makes the code a little bit confusing. If you say
>
> x = some_intermediate_result(...)
> do_something_with (x)
>
> do you know for sure whether x will be needed again?
Yes.
> Are you sure you
> didn't use the name x further up in the function for something that's
> still needed?
>
Yes. Of course, otherwise I wouldn't have used it here, would I?
Meaningful names are the biggest help in avoiding errors like this. Are
you trying to suggest my memory's going? ;-)
> This is one of the areas where there's tension between Python the
> scripting language, that gains by saving a few keystrokes when
> throwing together a quick hack, and Python the language for developing
> long-lasting applications that have to be maintained by multiple people.
>
> In Haskell you can even have temporary variables inside an expression:
>
> x = y + y*y + 3 where y=5
>
> sets x to 33. I believe (not absolutely sure) that the scope of y is
> limited to that expression.
Well, as warts go the inability to tightly control the scope of
variables isn't really that terrible, is it?
def called(function):
function()
return called
then:
@called
def called():
<whatever>
;-)
--
-Scott David Daniels
scott....@acm.org
The point is something like: it's normal to write
if cond:
x = 7
do_something_with(x)
# now you don't care about x any more.
Years later, there's some production problem in the middle of the
night and someone has to put in a patch, and they re-use the value in
x for something later in the function, i.e.
y = x + 3 # since x is still in scope from way up there
and check it in. Years after THAT, yet another person re-uses the
name x for something, etc. Yeah, yeah, bad programming practice,
blah, blah, blah, but anyone who's maintained code in the real world
knows this stuff happens all the time.
> Well, as warts go the inability to tightly control the scope of
> variables isn't really that terrible, is it?
I wouldn't say it's as terrible as some things might be, but it
contributes to a sense of sloppiness about Python, that there are
always all these dirty dishes laying around. Even the encrustation we
call Perl doesn't have this problem; it can not only control scope,
but it has the -T (taint checking) feature that analyzes actual
dataflow from one variable to another and flags you if you do
something dangerous with unchecked user input. This turns out to be
very useful. I wish Python had something like it.
Argh--don't do this. It makes a mess for the guy (or gal) that comes
after you and has to understand the code. Our forefathers fought and
died so that we could have as many unique variable names as we like.
So use them!
I agree with this completely. My company has a rather large application
written in Python (http://www.goombah.com) and I find that lambdas make
code more concise and clear in a manner not unlike, for instance, list
comprehensions. I just don't see what gain would ensue from losing
them.
Gary
---
Gary Robinson
CTO
Emergent Music, LLC
grob...@goombah.com