PEP 289: Generator Expressions (please comment)

A

Alex Martelli

Daniel said:
Why should generator comprehension be useful only for arguments?

Nobody ever said it would be. RH's examples were all function
calls because that's an "obvious" use case.

counter proposal:
g[(p.score, p.name) for p in players ]

Looks like it's indexing g.
This works similar to r'\' for raw strings and u'x' for unicode strings.

Nope said:
This has the advantage that it can be more easily extended:
d[(p.name, p.score) for p in players] creates a dictionary

dict((p.name, p.score) for p in players)

will do it in a much more obvious way.
s[(p.score, p.name) for p in players] creates a sorted list

list.sorted((p.score, p.name) for p in players)

will do it in a much more obvious way, and also allow you to
specify such optional niceties as (e.g.) "key=" (in 2.4 --
and, btw, thanks to all of RH's work on the issue!).
and
p[$*-=%/sd/!] allows to embed perl code

If you want perl, you know where to find it.


Alex
 
W

Werner Schiendl

Alex said:
No, but, in all cases where the lack of parentheses would make the
syntax unclear, you do need parentheses even today to denote tuples.
Cfr:
[1,2,3]
versus
[(1,2,3)]
a list of three items, versus a list of one tuple.

ok, but that's the whole point (1,2,3) *is* a tuple.

but

[(1),(2),(3)]

is the same than

[1,2,3]

and

[(1)]

is the same than

[1]

if you want a 1-tuple in a list, you've to write

[(1,)]
The PEP *IS* "similar to tuples": parentheses are mandatory around a
generator expression wherever their lack would make things unclear
(and that's basically everywhere, except where the genexp is the
only argument to a function call). Hard to imagine a simpler rule.

With "similar to tuples" I meant the kind of indication that I want
a list with exactly one item that is a generator.
The idea of "adding a comma" like this:

[x for x in y, ] # List containing generator


feels totally arbitrary and ad-hoc to me, since there is NO other
natural connection between genexps and commas (quite differently
from tuples). Moreover, it would not help in the least in other
VERY similar and typical cases, e.g.:

[x for x in y, z,] # ok, now what...?

That's a reasonable point of course.

To be honest, I didn't consider that as I always put the items to
iterate over in an explicit list or tuple or have 'em already inside one.

There is no way to judge what's meant in that case, it's a little
unfortunate that this *is* currently allowed.

So within a list literal, the parentheses are required *sigh* since the
default would need to be that following values are the values to iterate
over.
No, really, this whole "trailing comma to indicate a genexp in one
very special case" idea is sort of insane. Compare with:

[x for x in y, z,] # same as [y, z]

[(x for x in y, z,)] # the [<genexp>] case

[(x for x in y), z,] # the [<genexp>, z] case

what could possibly be clearer? Not to mention the parens rule
is simple, universally applicable, breaks no backwards compat,
AND is far closer to the general case for tuples ("parens when
needed for clarity") than the "singleton tuple" case you seem
to have focused on.

The trailing comma rule *is* there in the language already.

The problem with my idea is with the possibility of a tuple without
parentheses in a list comprehension (as discussed above).


Still I do not like the follwing example from the specification:

g = (x**2 for x in range(10))

Whatfor are the parens?

To me this looks like requiring parens for

a = b + c


best regards

Werner
 
H

Holger Krekel

Alex said:
Although most people on python-dev and here seems to like this PEP I
think it generally decreases readability. The above constructs seem
heavy and difficult to parse and thus i am afraid that they interfere
with the perceived simplicity of Python's syntax.

Let's see: today, I could code:
sum([x*x for x in roots])
In 2.4, I will be able to code instead:
sum(x*x for x in roots)

Yes, Raymond send me some private mail already and i clarified
that i don't like list comprehension syntax as well :)

Actually i do like generator expressions *more* than list comprehensions
so i agree to your points that gen expressions do improve on the (rather
specific) list comprehensions.

Nevertheless, i have the impression that this kind of syntax (be it list
comprehension or generator expressions) somewhat decreases the
chances for "immediate" understanding of python code without knowing
the language much. It's likely that you need to parse generator
expressions in detail especially because they don't provide sharp
visual clues like indented blocks do. I do consider the "visual clues"
to be a strength of current python although you can always provide
examples with a language's syntax which are not readable.

Generator expressions will probably raise the barrier to understanding
python code without having appropriate knowledge but that may very well
prove to be worth it. We'll probably find out soon so i think we don't
need to argue a lot about it now. IOW, i am not completly opposed
to the PEP just a bit skeptical. And, btw, i appreciated very much,
that Guido made it clear from the start that Python 2.3 would be a
maintenance release with no changes to syntax. I am probably just
astonished at these huge syntax-threads all over python-dev :)

have fun,

holger
 
D

Duncan Booth

For example, see current tuple syntax:

... print type(x)
...
<type 'tuple'>


As the code shows, just putting parentheses around the value 5 doesn't
make it a tuple.

Just putting parentheses around something can change the type, if you pick
the right example:
print type(x)


And even closer to the list comprehension vs list containing generator
example:
 
D

Daniel Dittmar

Alex said:
counter proposal:
g[(p.score, p.name) for p in players ]

Looks like it's indexing g.
This works similar to r'\' for raw strings and u'x' for unicode
strings.

Nope, it's ambiguous, while <single letter> adjacent to '...' isn't.

Although I admit my proposal is flawed, the principle behind is is sound,
namely that syntax constructs should be recognisable at the start.
p[$*-=%/sd/!] allows to embed perl code

If you want perl, you know where to find it.

See how difficult it is even for you to recognize something if it isn't
introduced by the proper markers, in this case <sarkasm>?

Daniel
 
C

Christoph Becker-Freyseng

Bjorn said:
[...]

Something like:

compiler.parse("[x*x for x in roots]")

(not completely what you want, but close :)

-- bjorn

:)

Unfortunately I don't have time right now to play around with Pythons
Compiler/Parser as my Biophysics-study is quite time consuming now ...

cu Christoph Becker-Freyseng


(I've been offline for some days due to an failure of telekom.de)
 
A

Alex Martelli

Alex said:
Although most people on python-dev and here seems to like this PEP I
think it generally decreases readability. The above constructs seem
heavy and difficult to parse and thus i am afraid that they interfere
with the perceived simplicity of Python's syntax.

Let's see: today, I could code:
sum([x*x for x in roots])
In 2.4, I will be able to code instead:
sum(x*x for x in roots)

Yes, Raymond send me some private mail already and i clarified
that i don't like list comprehension syntax as well :)

Actually i do like generator expressions *more* than list comprehensions
so i agree to your points that gen expressions do improve on the (rather
specific) list comprehensions.

And therefore, since you ain't gonna take list comprehensions away,
you should be in favour, not against, generator expressions.

Personally, I agree with David Ascher's evaluation in the intro to Chapter 1
of "Python Cookbook" (end of p.2): "List comprehensions have clearly
become wildly successful". I have seen non-programmers just learning
programming and Python together "GET" list comprehensions AT ONCE,
particularly if they had ever seen typical set notation as used in maths,
but not only under such conditions. I do agree with you that generator
expressions are a further improvement (except in name -- sigh -- I wish
"iterator expressions" had prevailed instead!-).

Nevertheless, i have the impression that this kind of syntax (be it list
comprehension or generator expressions) somewhat decreases the
chances for "immediate" understanding of python code without knowing
the language much. It's likely that you need to parse generator

I've had substantial feedback from articles on Python I had written,
particularly on Italian magazines, and much of it was from people who
indeed don't know the language much (or at all). That feedback tells
me that list comprehensions were absolutely nothing like the obstacle
you fear, confirming my experiences with newbies. The things that DID
give non-Python-knowers _serious_ trouble were rather e.g.:

while <condition>:
<body>
else:
<something else>

NOBODY who doesn't have a good grasp of Python gets "immediate
understanding" of this -- *not one person* out of all I've talked about
this. A large majority imagines that the "else:" clause is executed if
the <condition> NEVER holds, the remaining minority just doesn't
get it at all, NOBODY guesses that this may have to do with whether
a "break" inside the said:
expressions in detail especially because they don't provide sharp
visual clues like indented blocks do. I do consider the "visual clues"
to be a strength of current python although you can always provide
examples with a language's syntax which are not readable.

Oh, the above example is quite readable and rich with visual clues --
it's just that its _semantics_ are totally anti-intuitive to all readers who
haven't studied Python pretty well. On the contrary, and I wish there
was a way to make a bet on this and settle it objectively, I claim e.g.:

print sum(x*x for x in thelist if x>10)

will be "immediately read" as "print the sum of the squares of those
elements of 'thelist' that are larger than 10" by a majority of the
readers (if anything, understandable confusion will come about the
fact that "print" has nothing whatsoever to do with the *printer*
that one may or may not have attached to one's computer, but
rather will normally display stuff on a terminal-window... the mental
disconnection of "print" from "printer" is NOT intuitive at all -- it just
SEEMS that way after one has been programming long enough!).

Of course, more complicated expressions will be harder to read --
but that's quite independent of whether those expressions will
be generator expressions or other kinds.

Generator expressions will probably raise the barrier to understanding
python code without having appropriate knowledge but that may very well
prove to be worth it. We'll probably find out soon so i think we don't
need to argue a lot about it now. IOW, i am not completly opposed
to the PEP just a bit skeptical.

We'll find out in, I suspect, well over a year (when 2.4 final is released
and gets widespread). And we'll "find out" on a purely anecdotal and
experiential basis, just as we have "found out" about list comprehensions
over the last few years, unless somebody has money burning in their
pocket to finance a systematic study, which I seriously doubt:).
And, btw, i appreciated very much,
that Guido made it clear from the start that Python 2.3 would be a
maintenance release with no changes to syntax. I am probably just

So did I! Great move.
astonished at these huge syntax-threads all over python-dev :)

I was anything but astonished -- a bunch of language enthusiasts
stopped from any _productive_ discussion of syntax changes for,
what, over two years (since the last alpha of 2.2 until now)...?! It's
not amazing that we'd be bubbling over now we have a chance...:).

Guido (with support from the usual adverse-to-any-change brigade)
will no doubt exert his usual veto right with the usual firmness, so
all of our threads are little more than a venting out of too-long
repressed energy, anyway:).


Alex
 
A

Alex Martelli

Daniel said:
Alex said:
counter proposal:
g[(p.score, p.name) for p in players ]

Looks like it's indexing g.
This works similar to r'\' for raw strings and u'x' for unicode
strings.

Nope, it's ambiguous, while <single letter> adjacent to '...' isn't.

Although I admit my proposal is flawed, the principle behind is is sound,
namely that syntax constructs should be recognisable at the start.

Avoiding lookahead is a good principle, but not an absolute.

For example, when I see a literal that starts with the characters:

1233445

I do NOT start grumbling that, since it violates the Dittmar Principle,
I'm desperate by not yet knowing after reading the first few characters
whether it's going to be an integer literal, such as

123344567

or a float literal, such as

1233445.67

Your "should" is just too weak to make this notation other than
perfectly fine. A language designed strictly by your principle, thus
forcing initial stropping of digit sequences to distinguish e.g.
integer literals from float ones, would be a syntax disaster.

p[$*-=%/sd/!] allows to embed perl code

If you want perl, you know where to find it.

See how difficult it is even for you to recognize something if it isn't
introduced by the proper markers, in this case <sarkasm>?

"Introduced" matters not a whit (just like the fact that, in English,
"sarcasm" is spelled with a c and not with a k). If you had chosen to
indicate your dubious sarcasm (against your own proposal?!) by a
trailing parenthetical such as "(just kidding)" I would not have
wasted the time to respond. Don't take the _complete_ lack of any
clarifying denotation (which is definitely a stupid choice) obscuring
the message, as any proof that the clarifying denotation must be
BEFORE rather than AFTER -- it just doesn't follow. As your proposal
DOES look distinctly perlish (cfr q/foo/ vs qq/foo/ etc), it's quite
reasonable to form the working hypothesis that you LIKE perl syntax,
rather than being engaged in sarcasm against your own proposals (which
is a form of split personality one rarely comes upon).


Alex
 
A

Alex Martelli

Werner said:
Alex said:
No, but, in all cases where the lack of parentheses would make the
syntax unclear, you do need parentheses even today to denote tuples.
Cfr:
[1,2,3]
versus
[(1,2,3)]
a list of three items, versus a list of one tuple.

ok, but that's the whole point (1,2,3) *is* a tuple.

It's a tuple in parentheses.

The parentheses are only necessary when the syntax would otherwise
be unclear, and THAT is the whole point.
<type 'tuple'>

See? "Look ma, no parentheses", because none are needed in the
assignment to x -- the tuple, by itself, is parentheses-less,
though people often (understandably) put redundant parentheses
around it anyway, just in case (so do repr and str when you
apply them to a tuple object, again for clarity).

Normally, tuples are indicated by commas; but when commas could
mean something else (list displays, function calls), then you
ALSO put parentheses around the tuple and thus clarify things
(you also must use parentheses to indicate an EMPTY tuple,
because there is no comma involved in that case).

if you want a 1-tuple in a list, you've to write

[(1,)]

Yes, and if you write [1,] WITHOUT the parentheses, that's
a list of one number, NOT a list of one tuple -- exactly my
point.
With "similar to tuples" I meant the kind of indication that I want
a list with exactly one item that is a generator.

So you parenthesize the one item to disambiguate, just like you
would parenthesize the one item to disambiguate if the one item
was a tuple such as
1,
rather than a genexp such as
x*x for x in foo

I.e., the proposed syntax, requiring parentheses, IS strictly
similar to the identical requirement for parentheses in tuples
(when either a tuple or a genexp happens to be the one item
in a list display).

To assign a one-item tuple to x you can write

x = 23,

the comma is what makes the tuple, and parentheses have nothing
to do with the case. You can of course choose to add redundant
parentheses, if you think they improve readability, just like
you can generally include redundant parentheses in just about
all kinds of expressions for exactly the same reason (e.g. you
fear a reader would not feel secure about operator priorities).

The difference between tuples and the proposed syntax for
genexps is that genexp are going to _require_ parentheses
around them -- unless the parentheses already "happen" to be
there, i.e., in the frequent case in which the genexp is the
only argument to a function or type call. Basically, that's
because, even though the _compiler_ would have no problems,
Guido judges that a _human reader_ might, in parsing

x = y for y in foo

as meaning

x = (y for y in foo)

and NOT the incorrect

(x = y) for y in foo

So the parentheses are mandated to make it clear beyond any
doubt that the former, NOT the latter, parse is meant.

The trailing comma rule *is* there in the language already.

A trailing comma is allowed in any "comma-separated list".
A tuple display is a comma-separated list.
Therefore, a tuple display allows a trailing comma.

[A SINGLETON tuple requires a trailing comma because commas
are what DEFINES that a tuple display is occurring -- except
in certain contexts such as list displays and function calls,
where the commas have another meaning, and for an empty
tuple, where commas are -- perhaps arbitrarily -- disallowed]

A genexp is not a comma-separated list, and has nothing to do
with comma-separated lists, therefor it would be entirely
arbitrary and capricious to inject commas in its syntax AT ALL.

Still I do not like the follwing example from the specification:

g = (x**2 for x in range(10))

Whatfor are the parens?

See above: to avoid humans misparsing the unparenthesized form
as the incorrect (g = x**2) for ...

To me this looks like requiring parens for

a = b + c

If there was any risk of humans misparsing this as the
incorrect (a = b) + c -- then parentheses around the RHS
might be prudent. Fortunately, in this case there is no
such risk. Generator expressions are novel enough that
Guido judges the risk would exist in their case, and most
particularly since assigning a genexp to a variable will be
extremely rare usage (could you point to a few compelling
use cases for it...?) -- therefore it's absolutely NOT a
bad idea to force the author of code for that rare case to
type a couple of extra characters to make his intentions
absolutely crystal-clear to human readers, who can easily
be unfamiliar with that rare case and will thus be helped.

The "a = b + c" case is exactly the opposite: it IS very
common, therefore [1] typical readers don't need help
parsing it because it's familiar to them AND [2] forcing
parentheses in a very common case would be cumbersome
(while it is not to force them in a very rare case).


Alex
 
D

Daniel Dittmar

Alex said:
reasonable to form the working hypothesis that you LIKE perl syntax,
rather than being engaged in sarcasm against your own proposals (which
is a form of split personality one rarely comes upon).

I don't like list comprehension when compared to Smalltalk code blocks,
so I was really looking for a way to keep any additional 'comprehension'
variants limited to one syntax rule. But it seems as if the current
trend in Python is toward succinctness. To paraphrase one poster: 'It is
documented, therefor it is explicit'. I try to keep quiet, enjoy the
parts of Python I like and wait for the tide to turn.

Daniel
 
R

Rocco Moretti

Alex said:
Werner said:
Alex said:
No, but, in all cases where the lack of parentheses would make the
syntax unclear, you do need parentheses even today to denote tuples.
Cfr:
[1,2,3]
versus
[(1,2,3)]
a list of three items, versus a list of one tuple.

ok, but that's the whole point (1,2,3) *is* a tuple.

It's a tuple in parentheses.

I've never bought the argument that "comma's make the tuple." All the
explanations I've seen seem to be a posteriori rationalizations by
people who are being a bit too "clever." (... no offense intended Alex.)

I base my interpretation of this on the fact that (as I understand it)
the comma explanation was brought up *after* the relevant semantics of
Python were coded.

To me, tuple packing/unpacking is a special case, not a general feature
of tuple notation. I claim as evidence the recent c.l.p thread about
"for d[n] in mylist:", etc. the ability to use a comma separated list in
such situations is a special case - it isn't *really* a tuple, the fact
that it is a tuple is an implementation detail. (Note that it may be a
*required* implementation detail, but that's neither here or there ...)

Of course, I'll change my opinion if Guido comes out and says that he
consciously intended all along for tuples to be defined by commas, and
the parenthesis were just there to disambiguate - but my guess is that
it's instead convergent evolution of separate ad hoc devices.
The parentheses are only necessary when the syntax would otherwise
be unclear, and THAT is the whole point.

"In the face of ambiguity, refuse the temptation to guess."

I'd say that by allowing for some instances the ability for tuples to go
around naked, the unparenthesized form is *still* ambiguous. The
argument "Well, for this case it can't be a tuple, because if it *was* a
tuple then it would be ambiguous" makes my head hurt. It seems a little
disingenuous to define language semantics by defining what something
*isn't*.
The difference between tuples and the proposed syntax for
genexps is that genexp are going to _require_ parentheses
around them -- unless the parentheses already "happen" to be
there, i.e., in the frequent case in which the genexp is the
only argument to a function or type call. Basically, that's
because, even though the _compiler_ would have no problems,
Guido judges that a _human reader_ might.

I was going to write a big rant on the fact that I have difficulties in
reading the genex as a "chunk", and how there should be some sort of
bracketing required, but Guido used/uses/will use his time machine to
deflate 9/10 of my argument.

So let me see if I have this correct:

(Long Answer)

Genex's are required to have parenthesis around them except when they
would yield double parenthesis i.e. ((...)) - and the only place where
this is relevant is in function calls with one argument, or with
creating a tuple. (As genex's as base class lists and as a parameter
list would be illegal.) But with creating a tuple, you have to have a
comma to create a singleton, so that case doesn't matter either.

As a parenthetical (sic.) note, the only other cases of 'double
brackets' are {(...)} and [(...)], as python doesn't use <...> as
brackets. The first is illegal anyway - you can't create a dictionary
with just a genex. The second is covered in the PEP - that is:

"""
[x for x in S] # This is a list comprehension.
[(x for x in S)] # This is a list containing one generator
# expression.
"""
*and* the former is depreciated in favor of list(<genex>).

(Short Answer)

Parenthesis are required around genex's except when they are the *only*
parameter to a function.

(Tuples?)

My only other concern is with tuples without parenthesis in the single
parameter to a function case, as they might be confused with multiple
parameter lists.

As I understand, the genex syntax is:

expression1 "for" expression2 "in" expression3a
or
expression1 "for" expression2 "in" expression3b "if" expression4

If expression1 is a tuple, it is required to have parenthesis. (Current
behavior of list comprehensions.)

If expression2 is a tuple, it can have parenthesis absent. (As it is
delimited between for and in.) Is this the same for genex's?

If expression3a is a tuple, it will be required to have parenthesis in
genex's. (They are currently optional for list comps.)

What about a tuple for expression3b? Are parenthesis required here?

Although it doesn't really make much sense, expression4 can be a tuple.
The PEP doesn't say, but am I correct in assuming that in such a
condition, expression4 would require parenthesis? (Parenthesis are
required for list comps, so I'm guessing the answer is yes.)

(Current Final short answer)

Parenthesis are required around genex's except when they are the *only*
parameter to a function. If either the first or last expression in a
genex is a tuple, they must have parenthesis around them.

....

I was against genex's without brackets, but with the requirements Guido
added, I'm not quite sure about it. My guess is that it's a "time will
tell" situation. I'll pass the buck to Guido.

-Rocco
 
C

Chris Wright

PEP 289 proposes stuff like
sum(x*x for x in roots)
min(d.temperature()*9/5 + 32 for d in days)
Set(word.lower() for word in text.split() if len(word) < 5)
dict( (k, somefunc(k)) for k in keylist )
dotproduct = sum(x*y for x,y in itertools.izip(xvec, yvec))
bestplayer, bestscore = max( (p.score, p.name) for p in players )


and it seems that it's been accepted.

I meekly accept the judgement of BDFL, but have a sneaking suspicion
that we're on the way to re-inventing the LOOP macro here!

I can see the appeal, but fear where it might lead us ...

cheers

Chris Wright
 
A

Alex Martelli

Rocco Moretti wrote:
...
I've never bought the argument that "comma's make the tuple." All the

So how do you explain:

x = 7,

print type(x)

pray?

To me, tuple packing/unpacking is a special case, not a general feature

That "7," up there is no packing nor unpacking. Just a tuple.

Of course, I'll change my opinion if Guido comes out and says that he
consciously intended all along for tuples to be defined by commas, and

Guido doesn't follow c.l.py, so if you're interested you'll have
to ask him directly. I think he's on record as saying so, more
than once, but can't be bothered to check -- this subthread's just
too silly and captious.

So let me see if I have this correct:

(Long Answer)

Genex's are required to have parenthesis around them except when they
would yield double parenthesis i.e. ((...)) - and the only place where
this is relevant is in function calls with one argument, or with
creating a tuple. (As genex's as base class lists and as a parameter
list would be illegal.) But with creating a tuple, you have to have a
comma to create a singleton, so that case doesn't matter either.

Right -- the "creating a tuple" wouldn't cause any double parentheses.

As a parenthetical (sic.) note, the only other cases of 'double
brackets' are {(...)} and [(...)], as python doesn't use <...> as
brackets. The first is illegal anyway - you can't create a dictionary
with just a genex. The second is covered in the PEP - that is:

"""
[x for x in S] # This is a list comprehension.
[(x for x in S)] # This is a list containing one generator
# expression.
"""
*and* the former is depreciated in favor of list(<genex>).

I think the spelling is "deprecated" -- and while I'd love it
to be, I don't think it is.

(Current Final short answer)

Parenthesis are required around genex's except when they are the *only*
parameter to a function. If either the first or last expression in a
genex is a tuple, they must have parenthesis around them.

Right, AFAIK.


Alex
 
R

Rocco Moretti

Alex said:
"""
[x for x in S] # This is a list comprehension.
[(x for x in S)] # This is a list containing one generator
# expression.
"""
*and* the former is depreciated in favor of list(<genex>).


I think the spelling is "deprecated" -- and while I'd love it
to be, I don't think it is.

Aha, yes.

From dictionary.com (Quoting the American Heritage Dictionary):

"""
de·pre·ci·ate:
1. To lessen the price or value of.
2. To think or speak of as being of little worth; belittle. See
Usage Note at deprecate.

dep·re·cate:
1. To express disapproval of; deplore.
2. To belittle; depreciate.

Usage Note: The first and fully accepted meaning of deprecate is
“to express disapproval of.” But the word has steadily encroached on the
meaning of depreciate. It is now used, almost to the exclusion of
depreciate, in the sense “to belittle or mildly disparage,” as in He
deprecated his own contribution. In an earlier survey, this newer sense
was approved by a majority of the Usage Panel.
"""

Deprecate also has an additional technical usage entry from the Jargon File.

And you are right on the deprecated status. Quoth the PEP:

"""
List comprehensions will remain unchanged. For example:

[x for x in S] # This is a list comprehension.
[(x for x in S)] # This is a list containing one generator
# expression.

Unfortunately, there is currently a slight syntactic difference. The
expression:

[x for x in 1, 2, 3]

is legal, meaning:

[x for x in (1, 2, 3)]

But generator expressions will not allow the former version:

(x for x in 1, 2, 3)

is illegal.

The former list comprehension syntax will become illegal in Python 3.0,
and should be deprecated in Python 2.4 and beyond.
"""

I originally misread this. It should mean:
[x for x in 1, 2, 3] - is deprecated.
[x for x in (1, 2, 3)] - remains valid.

-Rocco
 
I

Inyeol Lee

In fact, list comprehensions themselves become redundant syntactic
sugar under the new proposal:

[foo(x) for x in bar] ==> list(foo(x) for x in bar)

Is there any plan to deprecate list comprehension when we move to
Python3.0? I think the advantages are;

1. It's just a syntactic sugar, only saves 4 chars.

2. It solves loop variable leaking problem of list comprehension.
I think it causes less confusion to remove list comprehension than
to change the semantics of it not to leak loop variables when 3.0 comes.

3. We can
 
J

Jess Austin

Peter Norvig's creative thinking triggered renewed interest in PEP 289.
That led to a number of contributors helping to re-work the pep details
into a form that has been well received on the python-dev list:

http://www.python.org/peps/pep-0289.html

In brief, the PEP proposes a list comprehension style syntax for....

Toward the end of the PEP, we have the following:
The utility of generator expressions is greatly enhanced when
combined with >reduction functions like sum(), min(), and max().
Separate proposals are >forthcoming that recommend several new
accumulation functions possibly >including: product(), average(),
alltrue(), anytrue(), nlargest(), nsmallest().


This is great. I'd like to request that alltrue() and anytrue() be
renamed forall() and exists(), repsectively. It would allow:

def prime(x):
return forall(x%y for y in xrange(2, math.sqrt(x)))

etc. This is a an opportunity to be mathematically precise, and I
think we should be. Python is going to have the universal and
existential operators in a very general syntax, so let's celebrate it
a little.

later,
Jess
 
J

Jeremy Fincher

This is great. I'd like to request that alltrue() and anytrue() be
renamed forall() and exists(), repsectively.

While these are the mathematical names, I've almost always seen them
named "all" and "any" in the various (mostly functional) programming
languages I've seen them in.

Exists() also has the problem that to less mathematically-minded
people (or Perl programmers :)) it isn't exactly clear what it's
checking for. Certainly, one would expect a generator expressions
like "x%y for y in xrange(2, math.sqrt(x))" to "exist," since we can
see it in the code and look at it with our own eyes.

I think these names also read somewhat more clearly:

# Check if someone is yelling:
if all(str.isupper, line.split()):
print "Must be a flamewar."

and:

# Check if someone yelled at all:
if any(str.isupper, line.split()):
print "Someone yelled."

I believe both these examples are more easily readable with "all" and
"any" than they would be with "forall" and "exists."

Jeremy
 
A

Alex Martelli

Jeremy Fincher wrote:
...
I think these names also read somewhat more clearly:

# Check if someone is yelling:
if all(str.isupper, line.split()):
print "Must be a flamewar."

and:

# Check if someone yelled at all:
if any(str.isupper, line.split()):
print "Someone yelled."

I'm not sure what these calls are meant represent -- maybe an
interface similar to filter, i.e. a callable then a sequence?
The functions we're considering, whatever their names, would
in any case just take an iterator, so, e.g.:

if all(x.isupper() for x in line.split()):

and the like.

I believe both these examples are more easily readable with "all" and
"any" than they would be with "forall" and "exists."

I'll pass on that. Maybe. I think I still prefer alltrue and anytrue...


Alex
 
J

Jeremy Fincher

Alex Martelli said:
I'm not sure what these calls are meant represent -- maybe an
interface similar to filter, i.e. a callable then a sequence?
The functions we're considering, whatever their names, would
in any case just take an iterator, so, e.g.:

if all(x.isupper() for x in line.split()):

and the like.

Yeah, I suppose that is the case :) I was stuck in FP mode (and
without-generator-expressions mode; I use those two functions in my
own code all the time)
I'll pass on that. Maybe. I think I still prefer alltrue and anytrue...

I'm afraid those names would inspire people to write code like this:

alltrue(bool(x) for x in someIterable)

I think the "true" in the function names might make people think it
constrains the type to be a bool, which, if it resulted in code as
above, would definitely be unfortunate.

Jeremy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top