New 3.x restriction in list comprehensions
In Python2, you can transform: r = [] for x in 2, 4, 6: r.append(x*x+1) into: r = [x*x+1 for x in 2, 4, 6] In Python3, the first still works but the second gives a SyntaxError. It wants the 2, 4, 6 to have parentheses. The good parts of the change: + it matches what genexps do + that simplifies the grammar a bit (listcomps bodies and genexp bodies) + a listcomp can be reliably transformed to a genexp The bad parts: + The restriction wasn't necessary (we could undo it) + It makes 2-to-3 conversion a bit harder + It no longer parallels other paren-free tuple constructions: return x, y yield x, y t = x, y ... + It particular, it no longer parallels regular for-loop syntax The last part is the one that seems the most problematic. If you write for-loops day in and day out with the unrestricted syntax, you (or least me) will tend to do the wrong thing when writing a list comprehension. It is a bit jarring to get the SyntaxError when the code looks correct -- it took me a bit of fiddling to figure-out what was going on. My question for the group is whether it would be a good idea to drop the new restriction. Raymond
Personally, I tend to always add parens to tuple expressions since it removes any and all ambiguity about when they're required or ney. I'd actually prefer it if parens were always required, but can appreciate that might/would offend those who prefer otherwise.
for (a, b) in d.items(): ... process(a, b)
def items(t): ... return (a, b)
Always using parens means that when refactoring one can avoid the extra mental step of 'are the parens required in use with python feature <F>>' Additionally, in some language features, the use of parens has become required to squash warts:
try: ... a = b[k] except (KeyError, IndexError), no_item: ... a = handle(no_item)
Regards, Matt On Fri, 2010-09-17 at 12:44 -0700, Raymond Hettinger wrote:
In Python2, you can transform: r = [] for x in 2, 4, 6: r.append(x*x+1)
into:
r = [x*x+1 for x in 2, 4, 6]
In Python3, the first still works but the second gives a SyntaxError. It wants the 2, 4, 6 to have parentheses.
The good parts of the change: + it matches what genexps do + that simplifies the grammar a bit (listcomps bodies and genexp bodies) + a listcomp can be reliably transformed to a genexp
The bad parts: + The restriction wasn't necessary (we could undo it) + It makes 2-to-3 conversion a bit harder + It no longer parallels other paren-free tuple constructions: return x, y yield x, y t = x, y ... + It particular, it no longer parallels regular for-loop syntax
The last part is the one that seems the most problematic. If you write for-loops day in and day out with the unrestricted syntax, you (or least me) will tend to do the wrong thing when writing a list comprehension. It is a bit jarring to get the SyntaxError when the code looks correct -- it took me a bit of fiddling to figure-out what was going on.
My question for the group is whether it would be a good idea to drop the new restriction.
Raymond
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-------------------------------------------------------------- Ovi Mail: Making email access easy http://mail.ovi.com
On 17/09/2010 20:44, Raymond Hettinger wrote:
In Python2, you can transform:
r = [] for x in 2, 4, 6: r.append(x*x+1)
into:
r = [x*x+1 for x in 2, 4, 6]
In Python3, the first still works but the second gives a SyntaxError. It wants the 2, 4, 6 to have parentheses.
The good parts of the change: + it matches what genexps do + that simplifies the grammar a bit (listcomps bodies and genexp bodies) + a listcomp can be reliably transformed to a genexp
The bad parts: + The restriction wasn't necessary (we could undo it) + It makes 2-to-3 conversion a bit harder + It no longer parallels other paren-free tuple constructions: return x, y yield x, y t = x, y ... + It particular, it no longer parallels regular for-loop syntax
The last part is the one that seems the most problematic. If you write for-loops day in and day out with the unrestricted syntax, you (or least me) will tend to do the wrong thing when writing a list comprehension. It is a bit jarring to get the SyntaxError when the code looks correct -- it took me a bit of fiddling to figure-out what was going on.
My question for the group is whether it would be a good idea to drop the new restriction.
Listcomps look more like genexps than for loops, so they should probably have the same syntax retrictions (or lack of), IMHO.
On 9/17/2010 3:44 PM, Raymond Hettinger wrote:
In Python2, you can transform:
r = [] for x in 2, 4, 6: r.append(x*x+1)
for x in 2,4,6: yield x*x+1 also works in 2/3.x
into:
r = [x*x+1 for x in 2, 4, 6]
In Python3, the first still works but the second gives a SyntaxError. It wants the 2, 4, 6 to have parentheses.
The good parts of the change: + it matches what genexps do
Is the restriction necessary for genexps? If the parser could handle [x*x+1 for x in 2, 4, 6] is (x*x+1 for x in 2, 4, 6) impossible, perhaps due to paren confusion?
+ that simplifies the grammar a bit (listcomps bodies and genexp bodies) + a listcomp can be reliably transformed to a genexp
The bad parts: + The restriction wasn't necessary (we could undo it) + It makes 2-to-3 conversion a bit harder + It no longer parallels other paren-free tuple constructions: return x, y yield x, y t = x, y ... + It particular, it no longer parallels regular for-loop syntax
The last part is the one that seems the most problematic. If you write for-loops day in and day out with the unrestricted syntax, you (or least me) will tend to do the wrong thing when writing a list comprehension. It is a bit jarring to get the SyntaxError when the code looks correct -- it took me a bit of fiddling to figure-out what was going on.
My question for the group is whether it would be a good idea to drop the new restriction.
3.x is in a sense more consistent than 2.x in that converting a for loop with a bare tuple always requires addition of parentheses rather than just sometimes. Never requiring parens would be even better to me if it did not make the implementation too messy. -- Terry Jan Reedy
On Fri, Sep 17, 2010 at 21:44, Raymond Hettinger
My question for the group is whether it would be a good idea to drop the new restriction.
I like the restriction and would actually advocate having it for regular for-loops too (though that would be a big no-no, I guess). Here's why I never use them without parenthesis, in python 2:
(1 if True else 3, 4) (1, 4) (lambda x: x * x, 6) (
, 6) [i for i in 2, 3] [2, 3] (i for i in 2, 3) File "<stdin>", line 1 (i for i in 2, 3) ^ SyntaxError: invalid syntax
And in Python 3:
(1 if True else 3, 4) (1, 4) (lambda x: x * x, 6) (
, 6) [i for i in 2, 3] File "<stdin>", line 1 [i for i in 2, 3] ^ SyntaxError: invalid syntax (i for i in 2, 3) File "<stdin>", line 1 (i for i in 2, 3) ^ SyntaxError: invalid syntax
Cheers, Dirkjan
On Sat, Sep 18, 2010 at 8:00 AM, Dirkjan Ochtman
On Fri, Sep 17, 2010 at 21:44, Raymond Hettinger
wrote: My question for the group is whether it would be a good idea to drop the new restriction.
I like the restriction and would actually advocate having it for regular for-loops too (though that would be a big no-no, I guess).
Yep, I tend to parenthesise tuples even when it isn't strictly necessary as well. Even if the parser doesn't care, it makes it a lot easier for human readers (including myself when I have to go back and read that code). (I have similar objections to people that rely on precedence ordering too heavily in complicated expressions - even if the compiler understands them correctly, many readers won't know the precedence table off by heart. Judicious use of parentheses turns code those readers would otherwise have to think about into something which is obviously correct even at a glance). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On Fri, Sep 17, 2010 at 12:44 PM, Raymond Hettinger
In Python2, you can transform:
r = [] for x in 2, 4, 6: r.append(x*x+1)
into:
r = [x*x+1 for x in 2, 4, 6]
In Python3, the first still works but the second gives a SyntaxError. It wants the 2, 4, 6 to have parentheses.
The good parts of the change: + it matches what genexps do + that simplifies the grammar a bit (listcomps bodies and genexp bodies) + a listcomp can be reliably transformed to a genexp
The bad parts: + The restriction wasn't necessary (we could undo it) + It makes 2-to-3 conversion a bit harder + It no longer parallels other paren-free tuple constructions: return x, y yield x, y t = x, y ... + It particular, it no longer parallels regular for-loop syntax
The last part is the one that seems the most problematic. If you write for-loops day in and day out with the unrestricted syntax, you (or least me) will tend to do the wrong thing when writing a list comprehension. It is a bit jarring to get the SyntaxError when the code looks correct -- it took me a bit of fiddling to figure-out what was going on.
My question for the group is whether it would be a good idea to drop the new restriction.
This was intentional. It parallels genexps and it avoids an ambiguity (for the human reader -- I know the parser has no problem with it :-). Please don't change this back. (It would violate the moratorium too...) -- --Guido van Rossum (python.org/~guido)
participants (7)
-
Dirkjan Ochtman
-
Guido van Rossum
-
Matthew Russell
-
MRAB
-
Nick Coghlan
-
Raymond Hettinger
-
Terry Reedy