Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: what's wrong with "lambda x : print x/60,x%60"

2 views
Skip to first unread message

Ezequiel, Justin

unread,
Dec 5, 2005, 2:07:53 AM12/5/05
to pytho...@python.org
Try

lambda_hrs = lambda x: (x/60,x%60)

Gary Herron

unread,
Dec 5, 2005, 2:11:22 AM12/5/05
to Mohammad Jeffry, pytho...@python.org
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. 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.


Klaus Alexander Seistrup

unread,
Dec 5, 2005, 2:20:18 AM12/5/05
to
Justin Ezequiel wrote:

> 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/

bruno at modulix

unread,
Dec 5, 2005, 4:38:25 AM12/5/05
to
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.


--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'on...@xiludom.gro'.split('@')])"

Bengt Richter

unread,
Dec 5, 2005, 6:46:58 AM12/5/05
to
On Mon, 05 Dec 2005 10:38:25 +0100, bruno at modulix <on...@xiludom.gro> wrote:

>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

ru...@yahoo.com

unread,
Dec 5, 2005, 5:59:10 PM12/5/05
to

"Gary Herron" <ghe...@islandtraining.com> wrote in message
news:mailman.1600.1133766...@python.org...
> --snip--

> 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

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--

Sybren Stuvel

unread,
Dec 5, 2005, 6:27:17 PM12/5/05
to
ru...@yahoo.com enlightened us with:

> 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.

> 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

Fredrik Lundh

unread,
Dec 5, 2005, 6:33:17 PM12/5/05
to pytho...@python.org
Sybren Stuvel wrote:

> 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>

Paul Rubin

unread,
Dec 5, 2005, 6:42:06 PM12/5/05
to
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?

> > 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

bon...@gmail.com

unread,
Dec 5, 2005, 9:53:22 PM12/5/05
to

ru...@yahoo.com wrote:
> > 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.
>
Why would one need print in lambda ? I like ternary operator(and there
is ugly work around though still 100% functional). But print ?

Steve Holden

unread,
Dec 5, 2005, 10:08:43 PM12/5/05
to pytho...@python.org
ru...@yahoo.com wrote:
> "Gary Herron" <ghe...@islandtraining.com> wrote in message
> news:mailman.1600.1133766...@python.org...
>
>>--snip--
>>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
>
>
> 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.
>
I'm getting a little tired of "namespace pollution" being trotted out as
a reason to use lambda. Defining a function, and giving it a name, isn't
"polluting the namespace", any more than assigning sub-expressions to
temporary variables is polluting the namespace. Why use temporary
variables when all you have to do is make your expressions three lines
long to avoid "polluting the namespace"?

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/

Paul Rubin

unread,
Dec 5, 2005, 10:24:59 PM12/5/05
to
Steve Holden <st...@holdenweb.com> writes:
> Defining a function, and giving it a name,
> isn't "polluting the namespace", any more than assigning
> sub-expressions to temporary variables is polluting the namespace.

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.

bon...@gmail.com

unread,
Dec 5, 2005, 10:31:46 PM12/5/05
to

Paul Rubin wrote:
> > 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.

For some people, the second form is clearer.

ru...@yahoo.com

unread,
Dec 6, 2005, 12:10:57 AM12/6/05
to

I dashed that last part off quickly, so I don't have a good reason.
Maybe to insert a debugging print temporarily?

bon...@gmail.com

unread,
Dec 6, 2005, 1:02:12 AM12/6/05
to
If one needs it for debugging, it raise an alarm bell if lambda is the
right thing to use. Though it is still doable, in a hackary way :

def debug(x): print x

reduce(lambda x,y: (x+y, debug(x))[0], range(10))

Devan L

unread,
Dec 6, 2005, 1:21:59 AM12/6/05
to
Steve Holden wrote:
> ru...@yahoo.com wrote:
> > "Gary Herron" <ghe...@islandtraining.com> wrote in message
> > news:mailman.1600.1133766...@python.org...
> >
> >>--snip--
> >>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
> >
> >
> > 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.
> >
> I'm getting a little tired of "namespace pollution" being trotted out as
> a reason to use lambda. Defining a function, and giving it a name, isn't
> "polluting the namespace", any more than assigning sub-expressions to
> temporary variables is polluting the namespace. Why use temporary
> variables when all you have to do is make your expressions three lines
> long to avoid "polluting the namespace"?

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)

;-)

Dan Bishop

unread,
Dec 6, 2005, 1:30:36 AM12/6/05
to

There's also

lambda x, y: sys.stdout.write('%s\n' % x) or x + y

Antoon Pardon

unread,
Dec 6, 2005, 3:30:59 AM12/6/05
to
Op 2005-12-06, bon...@gmail.com schreef <bon...@gmail.com>:

But there is no suggestion that this should be the obligatory form.

--
Antoon Pardon

bon...@gmail.com

unread,
Dec 6, 2005, 3:52:00 AM12/6/05
to

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.

Paul Rubin

unread,
Dec 6, 2005, 4:04:09 AM12/6/05
to
bon...@gmail.com writes:
> 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 ;-).

Antoon Pardon

unread,
Dec 6, 2005, 4:08:52 AM12/6/05
to

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

bon...@gmail.com

unread,
Dec 6, 2005, 4:12:02 AM12/6/05
to

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.

Steve Holden

unread,
Dec 6, 2005, 5:59:04 AM12/6/05
to pytho...@python.org
There's a balance to be struck. Some of it will depend on personal
taste, and no matter how prescriptive "the rules" may be there is and
always should be room for some degree of personal style.

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.

Fredrik Lundh

unread,
Dec 6, 2005, 6:10:39 AM12/6/05
to pytho...@python.org
Steve Holden wrote:

> 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>

Antoon Pardon

unread,
Dec 6, 2005, 7:11:49 AM12/6/05
to
Op 2005-12-06, Fredrik Lundh schreef <fre...@pythonware.com>:

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

Sybren Stuvel

unread,
Dec 6, 2005, 8:04:47 AM12/6/05
to
Fredrik Lundh enlightened us with:

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?

Steve Holden

unread,
Dec 6, 2005, 8:19:26 AM12/6/05
to pytho...@python.org
Sybren Stuvel wrote:
> Fredrik Lundh enlightened us with:
>
>>>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!
>
>
> 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)

Sybren Stuvel

unread,
Dec 6, 2005, 12:11:50 PM12/6/05
to
Steve Holden enlightened us with:

> 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 ;-)

Steven D'Aprano

unread,
Dec 7, 2005, 4:42:26 AM12/7/05
to

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.

Sybren Stuvel

unread,
Dec 7, 2005, 4:59:09 AM12/7/05
to
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.

Antoon Pardon

unread,
Dec 7, 2005, 4:52:50 AM12/7/05
to
Op 2005-12-07, Steven D'Aprano schreef <st...@REMOVETHIScyber.com.au>:

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

Steven D'Aprano

unread,
Dec 7, 2005, 5:13:19 AM12/7/05
to

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.

Steve Holden

unread,
Dec 7, 2005, 5:12:35 AM12/7/05
to pytho...@python.org
Steven D'Aprano wrote:
[...]

> 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 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.

You must be some kind of Python neatnik! If I need the external
appearance of a module to be tidy I just use __all__.

Paul Rubin

unread,
Dec 7, 2005, 6:25:53 AM12/7/05
to
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

> 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.

Dan Sommers

unread,
Dec 7, 2005, 8:09:00 AM12/7/05
to
On 07 Dec 2005 03:25:53 -0800,

Paul Rubin <http://phr...@NOSPAM.invalid> wrote:

> 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

unread,
Dec 7, 2005, 12:10:08 PM12/7/05
to
On Wed, 07 Dec 2005 10:59:09 +0100, Sybren Stuvel wrote:

> 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.

Sybren Stuvel

unread,
Dec 7, 2005, 7:07:14 PM12/7/05
to
Steven D'Aprano enlightened us with:
> 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.

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.

Steve Holden

unread,
Dec 8, 2005, 4:59:46 AM12/8/05
to pytho...@python.org
Steven D'Aprano wrote:
> On Wed, 07 Dec 2005 10:59:09 +0100, Sybren Stuvel wrote:
[...]

> 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.
>
>
In cases like this you would be like the law, and not concern yourself
with trifles. In the majority of cases it costs you more to think about
this and do the typing than it saves.

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.

Steve Holden

unread,
Dec 8, 2005, 5:05:20 AM12/8/05
to pytho...@python.org
Paul Rubin wrote:
> 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
>
If this genuinely troubles you then you can always isolate the scope
with a function, though of course you also no longer have the code
inline then.

>
>>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?

Scott David Daniels

unread,
Dec 8, 2005, 3:04:45 PM12/8/05
to
Steve Holden wrote:
> Paul Rubin wrote:
>> .... 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
>>
> If this genuinely troubles you then you can always isolate the scope
> with a function, though of course you also no longer have the code
> inline then.
Or, if you must:

def called(function):
function()
return called

then:

@called
def called():
<whatever>

;-)

--
-Scott David Daniels
scott....@acm.org

Paul Rubin

unread,
Dec 8, 2005, 3:21:11 PM12/8/05
to
Steve Holden <st...@holdenweb.com> writes:
> > if cond:
> > my x = 7 # make a new scope for x, goes out of scope at end of if
> >
> If this genuinely troubles you then you can always isolate the scope
> with a function, though of course you also no longer have the code
> inline then.
> >>I don't generally speaking see the point:

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.

tut...@gmail.com

unread,
Dec 9, 2005, 11:41:29 AM12/9/05
to
Re using the same variable name over and over for different objects in
the same scope:

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!

garyrob

unread,
Dec 21, 2005, 1:17:16 PM12/21/05
to
> 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.

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

0 new messages