473,388 Members | 1,492 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

map/filter/reduce/lambda opinions and background unscientificmini-survey

Comrades,

During our current discussion of the fate of functional constructs in
python, someone brought up Guido's bull on the matter:

http://www.artima.com/weblogs/viewpost.jsp?thread=98196

He says he's going to dispose of map, filter, reduce and lambda. He's
going to give us product, any and all, though, which is nice of him.

What really struck me, though, is the last line of the abstract:

"I expect tons of disagreement in the feedback, all from ex-Lisp-or-Scheme
folks. :-)"

I disagree strongly with Guido's proposals, and i am not an ex-Lisp,
-Scheme or -any-other-functional-language programmer; my only other real
language is Java. I wonder if i'm an outlier.

So, if you're a pythonista who loves map and lambda, and disagrees with
Guido, what's your background? Functional or not?

tom

--
Batman always wins
Jul 19 '05
181 8578
Steven D'Aprano wrote:
This is something I've never understood. Why is it bad
form to assign an "anonymous function" (an object) to a
name?
Because it obfuscates your code for no benefit. You should avoid making it
hard for others to read your code (and 'others' includes yourself in the
future).

Also, it obfuscates tracebacks: all lambda expressions will identify in
tracebacks as <lambda>, but if you define a function you can give it a
meaningful name.

Why is it considered abuse of lambda to assign the
functions to a name? Is it an abuse of lambda to do this?

D = {"one": lambda noun: noun,
"two": lambda noun: noun + 's',
"many": lambda noun: 'lots of ' + noun + 's' }

assert D["two"]("python") == "pythons"

No, that is approaching a reasonable use of lambda, however I would still
be inclined to write it with functions. e.g.

def one(noun):
return noun

def two(noun):
return noun+'s'

def many(noun):
return 'lots of %ss' % (noun,)

D = dict(one=one, two=two, many=many)

although in this particular case I would probably just put format strings
in the dictionary:

def D(style, noun):
formats = dict(one="%s", two="%ss", many="lots of %ss")
return formats.get(style, "an indeterminate number of %ss") % (noun,)

assert D("two","python") == "pythons"
Jul 21 '05 #151
Agreed, I dislike map and its ilk as well.
However, they are handy in some cases. I particularly like the way Ruby
deals with this problem. Instead of all these functions, internal
iterators and true anonymous blocks are used.
Case in point:

def gt_than_5(obj):
return obj > 5
results = filter(gt_than_5, seq)

becomes

results = seq.find_all do |item|
item > 5
end

This has the advantage of writing less code for the common cases by
having them builtin to the class. Instead of everyone needlessly
recoding these over and over again, they're implemented in one place.
This could be done by defining an abstract class that enumerable
objects inherit from. It's not practical, but I can dream, can't I? ;-)
Also, you don't have to define a separate testing function. Granted, in
this case, the test func is trivial, but when it's non-trivial, you
really notice the advantages.

Ivan Van Laningham wrote:
Hi All--

Tom Anderson wrote:

Comrades,

"I expect tons of disagreement in the feedback, all from ex-Lisp-or-Scheme
folks. :-)"

I disagree strongly with Guido's proposals, and i am not an ex-Lisp,
-Scheme or -any-other-functional-language programmer; my only other real
language is Java. I wonder if i'm an outlier.

So, if you're a pythonista who loves map and lambda, and disagrees with
Guido, what's your background? Functional or not?


I'm a pythonista who doesn't love them. In fact, even though I've done
more than my fair share of lambda Tkinter programming using lambdas,
I've never been happy with lambda. And I've spent months inside of
Lisp/Emacs Lisp/Scheme, too (I have the world's second largest .emacs
file [my friend Andy Glew has the largest], even though I can't use it
on Windows;-). I find list comprehensions easier to understand than
map, and small named functions or, better yet, class methods, *tons*
easier to read/understand than lambda--there are too many restrictions
you have to remember.

Personally, I find that Lisp & its derivatives put your head in a very
weird place. Even weirder than PostScript/Forth/RPN, when you come
right down to it.

I won't miss them, but since I don't use them now, that doesn't mean a
whole lot.

Metta,
Ivan
----------------------------------------------
Ivan Van Laningham
God N Locomotive Works
http://www.andi-holmes.com/
http://www.foretec.com/python/worksh...oceedings.html
Army Signal Corps: Cu Chi, Class of '70
Author: Teach Yourself Python in 24 Hours


Jul 21 '05 #152
Tom Anderson wrote:
def flatten(ll):
return reduce(lambda a, l: a.extend(l), ll, [])

How would one do that as a list comp, by the way? I'm really not very good
with them yet.


Not really a list-comprehension based solution, but I think what you want is
ll=[[1,2],[3,4,5],[6]]
sum(ll,[])

[1, 2, 3, 4, 5, 6]

--
Pawe³ Sakowski <pa***@sakowski.pl>
Jul 21 '05 #153
On Thu, 07 Jul 2005 09:36:24 +0000, Duncan Booth wrote:
Steven D'Aprano wrote:
This is something I've never understood. Why is it bad
form to assign an "anonymous function" (an object) to a
name?
Because it obfuscates your code for no benefit. You should avoid making it
hard for others to read your code (and 'others' includes yourself in the
future).


I don't particularly think I'm that much smarter than the average
programmer. In fact I *know* that I'm not that much smarter. So why do I
see nothing obfuscated or obscure or difficult to understand in func =
lambda x: x**3 - 5*x when apparently most of the Python community find it
too complicated?

Whichever is "more readable" in the absolute sense, the "abused" lambda
expression above is within a gnat's whisker of the def equivalent,

def func(x):
return x**3 - 5*x

I honestly don't understand why it is supposed to be so hard to follow.

I can think of many function which should not be written with lambda, just
as some things shouldn't be written as list comps. But within the limits
of how much complexity you can reasonably include in a single expression,
I don't see why lambda puts people off.

I make it, eight mental tokens (not necessarily the same as Python tokens)
for the lambda versus nine for the def. A trivial difference. In my mind,
the tokens are:

func, =, lambda, x, :, x**3, -, 5*x

compared to:

def, func, (), x, :, return, x**3, -, 5*x

(Your mental parser may differ.)

Also, it obfuscates tracebacks: all lambda expressions will identify in
tracebacks as <lambda>, but if you define a function you can give it a
meaningful name.


Well there is that. If you have lots of lambdas assigned to names, I guess
debugging could be more difficult:

py> f = lambda x: 1.0/x
py> f(0)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 1, in <lambda>
ZeroDivisionError: float division
py> def f(x):
.... return 1.0/x
....
f(0)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in f
ZeroDivisionError: float division

So far so good. But then:

py> g = f
py> del f
py> g(0)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in f
ZeroDivisionError: float division

(but we actually got the error by calling g, not f, and in fact f no
longer exists at the point we called g)

Why is it considered abuse of lambda to assign the
functions to a name? Is it an abuse of lambda to do this?

D = {"one": lambda noun: noun,
"two": lambda noun: noun + 's',
"many": lambda noun: 'lots of ' + noun + 's' }

assert D["two"]("python") == "pythons"

No, that is approaching a reasonable use of lambda, however I would still
be inclined to write it with functions. e.g.

def one(noun):
return noun

def two(noun):
return noun+'s'

def many(noun):
return 'lots of %ss' % (noun,)

D = dict(one=one, two=two, many=many)


I find your version far more difficult to follow than mine.

Psychologically, I find that defs seem to carry significant mental weight
in a way that lambdas don't. Even though the lambda forms are
equivalent to the def forms, I find that the defs are more heavy-weight in
my conceptual map of the program than a lambda would be.

Put it this way: whenever I see a two-line def as above, I can't help
feeling that it is a waste of a def. ("Somebody went to all the trouble
to define a function for *that*?") Yet I would never think the same about
a lambda -- lambdas just feel like they should be light-weight.

Am I just weird?

--
Steven.
Jul 21 '05 #154
On 7 Jul 2005 03:34:16 -0700, "Chris Rebert (cybercobra)"
<cv******@gmail.com> declaimed the following in comp.lang.python:
Agreed, I dislike map and its ilk as well.
However, they are handy in some cases. I particularly like the way Ruby
deals with this problem. Instead of all these functions, internal
iterators and true anonymous blocks are used.
Case in point:

def gt_than_5(obj):
return obj > 5
results = filter(gt_than_5, seq)

becomes

results = seq.find_all do |item|
item > 5
end
Unfortunately, that simple case doesn't really assist your
viewpoint -- isn't it the same as the one-liner list-comp

results = [ x for x in seq if x > 5 ]

For this example, I find the list-comp cleaner than either of
the variants.

-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Jul 21 '05 #155
Steven D'Aprano wrote:
Put it this way: whenever I see a two-line def as above, I can't help
feeling that it is a waste of a def. ("Somebody went to all the trouble
to define a function for *that*?") Yet I would never think the same about
a lambda -- lambdas just feel like they should be light-weight.
Obviously we think differently there. I don't see why lambdas are any
different than single expression functions. I certainly don't think of them
as lighter weight; they take just as long to call; and they involve just as
much stack setup/tear down. On the other hand I don't consider functions as
heavyweight, I'm happy to define short helper functions anywhere I think it
makes the code more expressive.
Am I just weird?


No, just different[*]. There's nothing wrong with different.
[*] conclusion based entirely on your postings here. I have no evidence
beyond that.

Jul 21 '05 #156
=?ISO-8859-2?Q?Pawe=B3?= Sakowski <pa***@sakowski.pl> wrote:
ll=[[1,2],[3,4,5],[6]]
sum(ll,[])

[1, 2, 3, 4, 5, 6]


That's a great argument for list.__add__ having the semantics of
extend rather than append 8-)

--
\S -- si***@chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/
___ | "Frankly I have no feelings towards penguins one way or the other"
\X/ | -- Arthur C. Clarke
her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump
Jul 21 '05 #157
Reinhold Birkenfeld wrote:
Ron Adam wrote:

Given the statement:

a = None

And the following are all true:

a == None

Okay.

(a) == (None)

Okay.

(a) == ()

Whoops! a (which is None) is equal to the empty tuple (which is not None)?


It's not an empty tuple, it's an empty parenthesis. Using tuples it
would be.

(a,) == (,)

which would be the same as:

(,) == (,)
(None) == ()

Then this "conceptual" comparison should also be true:

if (None): == if ():
if (): == if:

I can't really see any coherent concept here.

Reinhold


It would work out that.

if: == if:

Does that help?

Cheers,
Ron

Jul 21 '05 #158
On 7 Jul 2005 15:46:23 GMT, Duncan Booth <du**********@invalid.invalid> wrote:
Steven D'Aprano wrote:
Put it this way: whenever I see a two-line def as above, I can't help
feeling that it is a waste of a def. ("Somebody went to all the trouble
to define a function for *that*?") Yet I would never think the same about
a lambda -- lambdas just feel like they should be light-weight.


Obviously we think differently there. I don't see why lambdas are any
different than single expression functions. I certainly don't think of them
as lighter weight; they take just as long to call; and they involve just as
much stack setup/tear down. On the other hand I don't consider functions as
heavyweight, I'm happy to define short helper functions anywhere I think it
makes the code more expressive.
Am I just weird?


No, just different[*]. There's nothing wrong with different.

[*] conclusion based entirely on your postings here. I have no evidence
beyond that.

I think def is a form of assignment, with the target binding name
specified inside the expression syntax instead of to the left of an '=' as usual. I.e.,

def f(args): suite

is like

f = def(args): suite

except that I can't use an arbitrary left-hand side in the assignment, such as

MyClass.method = def(self, args): suite
or
somedict['foo'] = def(self, args): suite

Personally, I think def(args): suite ought to be allowed as an expression that you could
put in parentheses like any other expression if you need/want to write it with multiple lines.
Obviously this could both replace and expand the functionality of lambda ;-)

Regards,
Bengt Richter
Jul 21 '05 #159
On Thu, 7 Jul 2005, Ron Adam wrote:
Stian Søiland wrote:
Or what about a recursive generator?

That's the sort of thing i like to see!
Ok, lets see... I found a few problems with the testing (and corrected
it) so the scores have changed. My sort in place routines were cheating
because the lists weren't reset between runs so it had the advantage
after the first time though of sorting already sorted list.
Aaagh, of course!
And Tom's recursive no copy had a bug which kept a reference to one of
it's arguments so it's output was doubling the list.
Oops. I really should have written tests as well as benchmarks.
And the hasattr function was slowing everyone down, so I inlined it for
everyone who used it. Using a 1000 item list and starting with a flat
list and increasing the depth (unflatten) to shallow, medium, and deep.
(but not so deep to cause recursion errors.)
I wrote a new and improved test harness myself, but left my laptop at
work, and haven't been in today due to the bombs :(. I ran tests out to
100 000 elements, and your implementation was still faster, although not
by a lot - but then i hadn't found the bugs you had, so it's all moot.
And the winners are...

Stians flatten generator is nearly tied with Tom's recursive zerocopy.
My nonrecursive inplace is faster for very shallow lists, but Tom's
quickly over takes it. I was able to improve my nonrecursive copy
flatten a bit, but not enough to matter.
I also came up with an improvement to my version that should cut down on
recursive calls - a sort of recursion unrolling. I doubt it wouldd make
much difference, though.
So Tom's recursive zerocopy is the overall winner with Stian's flatten
generator close behind and just barely winning out in the very deep
catagory.
\o/
But they're all respectable times so everyone wins. ;-)


Everyone shall have medals!

tom

--
They travel the world in their ice cream van ...
Jul 21 '05 #160
Steven D'Aprano wrote:
On Thu, 07 Jul 2005 09:36:24 +0000, Duncan Booth wrote:

Steven D'Aprano wrote:
This is something I've never understood. Why is it bad
form to assign an "anonymous function" (an object) to a
name?
Because it obfuscates your code for no benefit. You should avoid making it
hard for others to read your code (and 'others' includes yourself in the
future).


Use a descriptive name like this?

def get_the_cube_of_x_and_then_subtract_five_multiplie d_by_x(x):
x**3 - 5*x

I think I like the lambda version here. ;-)

It would probably have a name which refers to the context in which it's
used, but sometimes the math expression it self is also the most readable.
Put it this way: whenever I see a two-line def as above, I can't help
feeling that it is a waste of a def. ("Somebody went to all the trouble
to define a function for *that*?") Yet I would never think the same about
a lambda -- lambdas just feel like they should be light-weight.
In the case of an interface module you might have a lot of two like
def's that simply change the name and argument format so several modules
can use it and have a standard consistent or simplified interface.

The lambda may be perfectly fine for that. But why not use def?

func_x = lambda x: (someother_func_x(x,'value'))

def func_x(x): return someother_func_x(x,'value')

There's both nearly identical, but the def is understandable to
beginners and advanced python programs.
Cheers,
Ron

Am I just weird?


Aren't we all? ;-)

Jul 21 '05 #161
Tom Anderson <tw**@urchin.earth.li> writes:
Stian Søiland wrote:
Or what about a recursive generator?


That's the sort of thing i like to see!


That can be a neat method. It's a pretty verbose way to do flatten(),
but it's a good example:

def flatten(l):
for e in l:
if isinstance(e, list):
for f in flatten(e):
yield f
else:
yield e

for x in flatten([0, [1, 2, [3, 4], 5], 6, 7]):
whatever()

--
Björn Lindström <bk**@stp.ling.uu.se>
Student of computational linguistics, Uppsala University, Sweden
Jul 21 '05 #162
On Thu, 7 Jul 2005, Steven D'Aprano wrote:
On Wed, 06 Jul 2005 14:28:55 +0100, Tom Anderson wrote:
del -> delete
How about just getting rid of del? Removal from collections could be done
with a method call,


Which would be called object.del() I presume.


That would be fine.
And that opens a big can of worms.

Suppose we have a list L = [4, 3, 2, 1, 0], what should L.del(1) do?
Delete the item at index 1, just as del L[1] would.
It looks like it should result in L becoming [4, 3, 2, 0].
Why? I guess if you hadn't read the documentation and were just calling
methods at random, you might, but i can't think of any other case.
An easy mistake to make, if you forget that the argument is (presumably)
an index.
Not the kind of thing people tend to forget! There is the problem that
people might get del and remove mixed up; i didn't actually realise there
was a remove method on lists until i looked just now.
You could make it clear by insisting on L.del[1] but that requires a big
change in Python's syntax.
It would, so i wouldn't dream of insisting on it.
What should L.del() do, with no arguments? Raise an error?
Er, exactly the same as calling any other method with a wrong-length
argument list - a TypeError, i should think.
Now, you have something like this:

class thing:
pass
obj = thing()
obj.alpha = [4, 3, 2, 1, 0]
obj.beta = 5

Python's object model suggests that obj.alpha.del() should call alpha's
del method, in the same way that obj.alpha.append() would call alpha's
append method.
Exactly so.
So how do you delete obj.alpha? obj.del("alpha") might work. But what if
obj itself is a mapping, with a key "alpha" as well as an attribute
alpha. Which one should obj.del("alpha") delete?
I don't think objects should have a del method by default. I'd suggest a
delattr or removeattr builtin, working along the lines of getattr and
setattr, for this task.
Now, if you said that L.del() should raise an exception earlier, what
about obj.beta.del()?
Unless int has a del method, that would be an exception - an
AttributeError, to be precise.
Presumably every object automatically has a del method,
I'd say no, but for the sake of argument, let's say it does.
so you don't have to program a del method yourself. obj.del is a method
object. So it has a del method. (Yes, sometimes you want to delete
methods. Functions are first class objects in Python.) Which has a del
method. Which has a del method.
Right.
What should obj.del.del.del.del.del.del.del.del.del() do?
Raise a TypeError, since you haven't passed any parameters.

As for obj.del.del.del.del.del.del.del.del.del("del"), that's an
interesting one - it comes down to the question of whether those del
methods are the same object or not. I'd say not: for two objects a and b
of the same class, a.foo and b.foo are considered different objects in
python, and that applies here.
and i'm not convinced that deleting variables is something we really
need to be able to do (most other languages manage without it).


Most other languages don't have namespaces that can get polluted, or
on-the-fly creation of variables. Most other languages don't consider
variables to be simply attributes of a module object.


How much is that really used? And how many of those cases wouldn't be
covered by a delattr builtin?
And most other languages don't allow you to run interactive sessions
where it is easy to mistakenly make variables you don't want.

py> x = 1
py> u = x+2 # oops, typo, meant y not u
py> del u # prevent confusion in the programmer's mind

It is also useful sometimes to delete a module object from the top level
namespace before re-importing it, rather than merely reloading it. That
requires being able to delete a variable.
That's a very strong use case. However, it would be straightforward to
make variable deletion an interpreter thing rather than a language thing.
In summary: del being a keyword works. del() being an object method is
unclear, confusing and complicated.


Only if you give it the bizarre semantics you use above!

I think having del as a keyword is actually unhelpful, since it's
overloaded to do two quite different things - remove items from lists and
dicts, and expunge attributes from namespaces. Far better to do let lists
and dicts expose methods to let themselves be manipulated, and to play
with attributes through a uniform troika of {get, set, del}attr builtins.

tom

--
They travel the world in their ice cream van ...
Jul 21 '05 #163
Daniel Dittmar <da************@sap.corp> writes on Wed, 06 Jul 2005 16:12:46 +0200:
Peter Hansen wrote:
Arguing the case for del: how would I, in doing automated testing,
ensure that I've returned everything to a "clean" starting point in
all cases if I can't delete variables? Sometimes a global is the
simplest way to do something... how do I delete a global if not with
"del"?

globals ().__delitem__ (varname)

except that the method would probably be called delete.


You now have a uniform way to remove an object from a namespace.

Why would you want to give each namespace its own method to
remove objects from it?

Can you imagine how much code you would break (would your proposal
to remove "del" got accepted)?
Dieter
Jul 21 '05 #164
> Am I just weird?

I feel the same way about where to use lambda's and where *not*
I come from C and C++ background and defining a function at the top
level (no nested functions) would always require good reasons

function name has to be remembered, to put it in other words it has to
be added in a mental list of available function
and writing a 2 liner function would only cause call overhead
(if not inlined) this may be the reason why "def" feels to me to have
more weight as "lambda"
usually you define lambda and forget it, no wasted time to find proper
name, which may also pollute the namespace
I find it more clear solution, it's concise

Jul 21 '05 #165
The difference in readability between

func = lambda x: x**3 - 5*x

def func(x):
return x**3 - 5*x

def func(x): return x**3 - 5*x

is obviously a matter of personal vision.

The fuctional difference (and, I believe, the only difference) is that the
def form attaches the specific name 'func' to the function object as its
func_name attribute while the lambda form attaches the generic 'name'
'<lambda>'. This makes tracebacks, for instance, less informative.

The reason some think the name=lambda form an abuse is that it is a second
way to do almost the same thing (with the functional difference being a
negative) while ignoring the intended purpose of lambda's presence in the
language. (But I will not argue this either way.)

Terry J. Reedy

Jul 21 '05 #166

"Pawe³ Sakowski" <pa***@sakowski.pl> wrote in message
news:da**********@inews.gazeta.pl...
Tom Anderson wrote:
def flatten(ll):
return reduce(lambda a, l: a.extend(l), ll, [])

How would one do that as a list comp, by the way? I'm really not very
good
with them yet.


Not really a list-comprehension based solution, but I think what you want
is
ll=[[1,2],[3,4,5],[6]]
sum(ll,[])

[1, 2, 3, 4, 5, 6]

Unless sum knows to typecheck input items and special-case lists and use
list.extend rather than list+list, this turns an O(n) operation into an
O(n**2) operation. Sum is meant for numbers.

Terry J. Reedy

Jul 21 '05 #167
On Wednesday 06 July 2005 09:41 am, Steven Bethard wrote:
Terry Hancock wrote:
And a syntax just occured to me -- what about this:
[<expression> for <argument list>]


If you haven't already, see:
http://wiki.python.org/moin/AlternateLambdaSyntax
for other similar proposals.


Yeah, it's basically "Robert Brewer: for (no-parens) syntax
[3]" isn't it (except that his eliminates the [], which is
probably saner).

But hey, it's surely a good thing (in the sense of being
more obvious) that it occured to me independently,
right? ;-)

--
Terry Hancock ( hancock at anansispaceworks.com )
Anansi Spaceworks http://www.anansispaceworks.com

Jul 21 '05 #168

"Stian Søiland" <st***@soiland.no> wrote in message
news:20********************@itea.ntnu.no...
On 2005-07-06 02:46:27, George Sakkis wrote:
So, who would object the full-word versions for python 3K ?
def -> define
del -> delete
exec -> execute
elif -> else if
Objections for the "else if" might be that it sounds like you can
replace "else if" with "else x=94" if you want. Thumbs up for "else if"
because it explains what it is much better than "elif". "elseif" ?


Today, on pydev list, in thread Chaining try statements: eltry?,
Guido said 'and in fact I sometimes think it was
a mistake to introduce elif just to save typing "else if".'

So maybe this will be reconsidered for 3.0

Terry J. Reedy

Jul 21 '05 #169
On Wednesday 06 July 2005 08:38 am, Tom Anderson wrote:
On Wed, 6 Jul 2005, Terry Hancock wrote:
With list comprehensions and generators becoming so integral, I'm
not sure about "unpythonic".
I'm going to resist the temptation to argue that list comps are themselves
unpythonic :).


Ah, but GvR likes them, so that pretty much makes them "pythonic"
by definition, doesn't it? ;-)
Hang on, where's the punctuation in either of those? They *are* done with
keywords!


Yeah, that's true, and it could be true here too, if you throw away the
[]. I see that's one of the proposed alternatives.

--
Terry Hancock ( hancock at anansispaceworks.com )
Anansi Spaceworks http://www.anansispaceworks.com

Jul 21 '05 #170
In <sF********************@tornado.tampabay.rr.com> , Ron Adam wrote:
Reinhold Birkenfeld wrote:
Ron Adam wrote:
(a) == ()

Whoops! a (which is None) is equal to the empty tuple (which is not None)?


It's not an empty tuple, it's an empty parenthesis. Using tuples it
would be.


But empty parenthesis are parsed as empty tuple::

In [8]: type( () )
Out[8]: <type 'tuple'>

Ciao,
Marc 'BlackJack' Rintsch
Jul 21 '05 #171
Duncan Booth wrote:
Peter Hansen wrote:
Tom Anderson wrote:
How about just getting rid of del?


Arguing the case for del: how would I, in doing automated testing,
ensure that I've returned everything to a "clean" starting point in all
cases if I can't delete variables? Sometimes a global is the simplest
way to do something... how do I delete a global if not with "del".


I generally find that unit tests force me to structure the code in a
cleaner manner, e.g. to not use globals as much, but if you do need to
delete a global you do it in exactly the same way as you delete anything:
use the "del" statement:


Umm: huh? Tom suggested getting rid of del, I suggested it was required
for some cases in doing testing in the fact of globals (for cases where
they are the simplest approach), then you suggest that the correct
approach is to use "del".

Well, I agree (including your point on use of globals, which I attempted
to anticipate with my comment starting "sometimes"), but I don't really
see the point of your posting, Duncan... it appears redundant on all
counts.

-Peter
Jul 21 '05 #172
Terry Hancock wrote:
With list comprehensions and generators becoming so integral, I'm
not sure about "unpythonic". And a syntax just occured to me --
what about this:

[y*x for x,y]

?

(that is:

[<expression> for <argument list>]

It's just like the beginning of a list comprehension or generator, but
without the iterator. That implies that one must be given, and
the result is therefore a callable object.


As others have mentioned, this looks too much like a list comprehension
to be elegant, which also rules out () and {}... but I really do like
the infix syntax.

Perhaps using angle-brackets would be useful? These have no
grouping-meaning in Python that I'm aware of. Example,

<y*x for x,y>

I'd also prefer using 'with' rather than 'for' as the keyword -- 'with'
doesn't suggest iteration. I also suggest parenthization of the
argument list, since that makes a zero-argument lambda not look weird.

To replicate the examples from
http://wiki.python.org/moin/AlternateLambdaSyntax

1 lambda a, b, c:f(a) + o(b) - o(c)
<f(a) + o(b) - o(c) with (a, b, c)>
2 lambda x: x * x
<x * x with (x)>
3 lambda : x
<x with ()>
4 lambda *a, **k: x.bar(*a, **k)
<x.bar(*a, **k) with (*a, **k)>
5 ((lambda x=x, a=a, k=k: x(*a, **k)) for x, a, k in funcs_and_args_list)
(<x(*a,**k) with (x=x, a=a, k=k)> for x, a, k in funcs_and_args_list)
Jul 21 '05 #173
Ron Adam wrote:
It's not an empty tuple, it's an empty parenthesis. Using tuples it
would be.

(a,) == (,)

which would be the same as:

(,) == (,)

() () a = ()
type(a) <type 'tuple'> (,)

File "<stdin>", line 1
(,)
^
SyntaxError: invalid syntax

You've wandered way off into the woods now.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
But since when can wounded eyes see / If we weren't who we were
-- Joi
Jul 21 '05 #174
Christopher Subich wrote:
As others have mentioned, this looks too much like a list comprehension
to be elegant, which also rules out () and {}... but I really do like
the infix syntax.


Why would it rule out ()?

You need to put a lambda express in ()'s anyways if you want to use it
right away.

print (lambda x,y:x+y)(1,2)

If you don't use the ()'s it reads the y(1,2) as part of the lambda
expression, might as well require the ()'s to start with rather than
leave it open for a possible error.
You could even say () is to function as [] is to list.

a function : name(args) -> returns a value

a list : name[index] -> returns a value

My choice:

name = (let x,y return x+y) # easy for beginners to understand
value = name(a,b)

value = (let x,y return x+y)(a,b)

I think the association of (lambda) to[list_comp] is a nice
distinction. Maybe a {dictionary_comp} would make it a complete set. ;-)

Cheers,
Ron





Jul 21 '05 #175
Erik Max Francis wrote:
Ron Adam wrote:
It's not an empty tuple, it's an empty parenthesis. Using tuples it
would be.

(a,) == (,)

which would be the same as:

(,) == (,)


>>> () () >>> a = ()
>>> type(a) <type 'tuple'> >>> (,) File "<stdin>", line 1
(,)
^
SyntaxError: invalid syntax

You've wandered way off into the woods now.


Yes, ummm seems soo... err.

This is one of those Python isn't quite consistent for practical reasons
area. I don't create empty tuples that way very often, but [] is to ()
is to {} is pretty obvious so I don't really have a good excuse.
(1) 1 () ()
(((((1))))) 1 ((()))

()

Well in my previous explanation I *mean* it to be empty parenthesis.

Does that help?

Cheers,
Ron
Jul 21 '05 #176
Ron Adam wrote:
Well in my previous explanation I *mean* it to be empty parenthesis.

Does that help?


Maybe it might be beneficial to learn a little more of the language
before proposing such wide-reaching (and un-Pythonic) reforms?

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
But since when can wounded eyes see / If we weren't who we were
-- Joi
Jul 21 '05 #177
Erik Max Francis wrote:
Ron Adam wrote:
Well in my previous explanation I *mean* it to be empty parenthesis.

Does that help?

Maybe it might be beneficial to learn a little more of the language
before proposing such wide-reaching (and un-Pythonic) reforms?


Hi Erik,

Getting more sleep is the answer to not making those kinds of oversights
in this case.

It's really was not a (my) proposal, but a suggestion someone else made.
It seemed like an interesting idea and I wanted to see what kind of
problems and benefits it would have. Discussing an idea with other
before it's fully thought out is a good way to explore its possibilities
even though it may mean appearing silly at times, which I don't mind. :)

In the previous posts I was attempting to show a possible pattern or
logic which doesn't currently correspond to the languages syntax using
parenthesis.
(None)


That's as close to an empty parenthesis as Python gets. I was really
trying to explain an underlying concept, not show actual python code.

And the conclusion (opinion) I've come to, is such a change might be
made to work, but it would be very confusing to most people who have
gotten use to the current None usage. And difficult to emplement in a
way that's consistant overall.

An alternative is to use a different word such as 'undefined'. Then
None can be used as it is currently, and undefined, can be used to test
for in a comparison for undefined names. Assigning a name to undefined
could be used as an alternative to delete a name but so far I don't see
an advantage to doing that way over using del.

if name is undefined: do something.

Instead of:

try:
name
except:
do something
And maybe:

name = undefined

can be used in expressions where del name can't?

But so far this doesn't seem useful enough to propose and it would
probably cause more problems (or confusion) than it solves.

Cheers,
Ron
Jul 21 '05 #178
Ron Adam wrote:
Christopher Subich wrote:
As others have mentioned, this looks too much like a list
comprehension to be elegant, which also rules out () and {}... but I
really do like the infix syntax.

Why would it rule out ()?


Generator expressions. Mind you, Py3k might want to unify generators
and lists in some way anyway, freeing up (). :)

You need to put a lambda express in ()'s anyways if you want to use it
right away.

print (lambda x,y:x+y)(1,2)
Although print <x+y with (x,y)>(1,2) has natural grouping: the lambda
itself is effectively a single token. I also like the infix style
reminiscent of Python's existing comprehensions.

Hell, call it a 'function comprehension' or 'expression comprehension,'
and we can pretend we invented the damn thing.
My choice:

name = (let x,y return x+y) # easy for beginners to understand
value = name(a,b)

value = (let x,y return x+y)(a,b)
And a zero-argument lambda is (aside from really arcane)?
(let return 2)?
I think the association of (lambda) to[list_comp] is a nice
distinction. Maybe a {dictionary_comp} would make it a complete set. ;-)


Yeah, dictionary comprehensions would be an interesting feature. :)
Syntax might be a bit unwieldy, though, and I doubt they'd be used often
enough to be worth implementing, but still neat.
Jul 21 '05 #179
Christopher Subich wrote:
Ron Adam wrote:
I think the association of (lambda) to[list_comp] is a nice
distinction. Maybe a {dictionary_comp} would make it a complete set. ;-)


Yeah, dictionary comprehensions would be an interesting feature. :)
Syntax might be a bit unwieldy, though, and I doubt they'd be used often
enough to be worth implementing, but still neat.


Dict comprehensions were recently rejected:
http://www.python.org/peps/pep-0274.html
The reason, of course, is that dict comprehensions don't gain you much
at all over the dict() constructor plus a generator expression, e.g.:
dict((i, chr(65+i)) for i in range(4))

STeVe
Jul 21 '05 #180
"Steven Bethard" <st************@gmail.com> wrote:
Christopher Subich wrote:
Ron Adam wrote:
I think the association of (lambda) to[list_comp] is a nice
distinction. Maybe a {dictionary_comp} would make it a complete set. ;-)


Yeah, dictionary comprehensions would be an interesting feature. :)
Syntax might be a bit unwieldy, though, and I doubt they'd be used often
enough to be worth implementing, but still neat.


Dict comprehensions were recently rejected:
http://www.python.org/peps/pep-0274.html
The reason, of course, is that dict comprehensions don't gain you much
at all over the dict() constructor plus a generator expression, e.g.:
dict((i, chr(65+i)) for i in range(4))


Sure, but the same holds for list comprehensions: list(i*i for i in
xrange(10)). The difference is historic I guess; list comprehensions
preceded generator expressions and so they cannot be removed, at least
not before 3.0. I wonder if they will/should be in the language when
the constraint of backwards compatibility is lifted. IMO they should
not (TIOOWTDI, uniformity among builtin data structures, not
overwhelmingly more useful than set or dict comprehensions), but
there's a long way till that day.

George

Jul 21 '05 #181

"George Sakkis" <gs*****@rutgers.edu> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
"Steven Bethard" <st************@gmail.com> wrote:
Dict comprehensions were recently rejected:
http://www.python.org/peps/pep-0274.html
The reason, of course, is that dict comprehensions don't gain you much
at all over the dict() constructor plus a generator expression, e.g.:
dict((i, chr(65+i)) for i in range(4))
Sure, but the same holds for list comprehensions: list(i*i for i in
xrange(10)). The difference is historic I guess; list comprehensions
preceded generator expressions and so they cannot be removed, at least
not before 3.0. I wonder if they will/should be in the language when
the constraint of backwards compatibility is lifted.
Guido has asked himself the same question. Some developers who love l.c.s
are sure they will stay. I am not. I think it might depend on whether
they have any real advantages in the context of the 3.0 engine and design,
which don't exist yet.
IMO they should
not (TIOOWTDI, uniformity among builtin data structures, not
overwhelmingly more useful than set or dict comprehensions), but
there's a long way till that day.


Yes.

Terry J. Reedy

Jul 21 '05 #182

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

226
by: Stephen C. Waterbury | last post by:
This seems like it ought to work, according to the description of reduce(), but it doesn't. Is this a bug, or am I missing something? Python 2.3.2 (#1, Oct 20 2003, 01:04:35) on linux2 Type...
4
by: Ben | last post by:
Hi all, I'm trying to figure out how how complex map, filter and reduce work based on the following piece of code from http://www-106.ibm.com/developerworks/linux/library/l-prog.html : ...
5
by: Logan | last post by:
I read in PEP 279 the following comment by GvR: "filter and map should die and be subsumed into list comprehensions, not grow more variants." Actually, I am using 'filter' and 'map' a lot in...
2
by: Thomas Philips | last post by:
To experiment with filtering, I define a function f(x,k) as follows >>> def f(x,k=2): return x%k==0 I can check that it works by typing >>> f(10,3) False Now, I try to filter a range using...
4
by: Charlie Taylor | last post by:
I find that I use lambda functions mainly for callbacks to things like integration or root finding routines as follows. flow = integrate(lambda x: 2.0*pi * d(x)* v(x) * sin(a(x)),xBeg, xEnd) ...
22
by: Cameron Laird | last post by:
QOTW: "... and to my utter surprise it worked." - Andrew Nagel on his move from wxPython to programming Tkinter in desperation "Python has more web application frameworks than keywords." - Skip...
9
by: lars_woetmann | last post by:
I have a list I filter using another list and I would like this to be as fast as possible right now I do like this: i tried using the method filter: filter(lambda x: x not in list2, list1)
10
by: charles.hebert | last post by:
Hi, Can anybody tell me how to to find the nearest value to zero in a list ? To do that, i'm using list comprenhension : Something simpler ?
7
by: cnb | last post by:
This must be because of implementation right? Shouldn't reduce be faster since it iterates once over the list? doesnt sum first construct the list then sum it? ----------------------- reduce...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.