('blue', 'red', 'orange' if something, 'green')

Here's an idea that would have helped me today while coding. Allow something like this: ('blue', 'red', 'orange' if some_condition, 'green') So 'orange' is included in the tuple only if `some_condition` evaluates to `True`. This could be applied to list literals, tuple literals, set literals, and possibly dict literals, though the latter might be too clunky. I expect this to be rejected, but I really couldn't think of an elegant way to achieve the same thing with existing syntax. Ram.

On Fri, Apr 22, 2011 at 11:59 AM, cool-RR <cool-rr@cool-rr.com> wrote:
First note: If you can just remove an element in the middle and still have the same time of object, then logically it would be a list, not an array. But things that semantically are lists are indeed sometimes made array for performance reasons, so that's not a weird thing to do. Having said that, I don't think it's going to make it. Normally there's exactly one element between each pair of commas; if we're going to give up that, I'm not sure this is the best way to do it. As for other ways to do it, they are not as elegant but they certainly do exist: ('blue', 'red') + (('orange',) if some_condition else ()) + 'green' [c for c in ('blue', 'red', 'orange', 'green') if c != 'orange' or some_condition] -- André Engels, andreengels@gmail.com

On Fri, Apr 22, 2011 at 7:59 PM, cool-RR <cool-rr@cool-rr.com> wrote:
colours = 'blue red orange green'.split() if not some_conditions: colours.remove('orange') There are lots of options, but most of them start by not using a tuple for a variable length sequence of like items. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Fri, Apr 22, 2011 at 12:42 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
I see. It's about as elegant as the other suggestions. And it's pretty annoying to use a list when I really wanted to use a tuple. Yeah, I can convert it to a tuple at the end, but that's just making it more verbose. Ram.

On Fri, Apr 22, 2011 at 12:52 AM, Andre Engels <andreengels@gmail.com> wrote:
Exactly. Ignoring memory/performance differences, the semantic reason to use a tuple instead of a list is that you have group of things _and their ordering matters_. If you can arbitrarily omit some items in the sequence, it's not a tuple; it's a list. (Or maybe even a set.)

On Fri, Apr 22, 2011 at 12:52 PM, Andre Engels <andreengels@gmail.com>wrote:
"This kind of semantics"? What semantics did we have here except filtering items before putting them in the sequence? How is that more list-y than tuple-y? If I removed items *after* constructing the sequence, it'd be list-y, but since I want to do it *before* the construction, I think it doesn't make it list-y. I used a tuple in this case because it's something that I wanted to stay immutable. Ram.

On Fri, Apr 22, 2011 at 6:57 AM, cool-RR <cool-rr@cool-rr.com> wrote:
I used a tuple in this case because it's something that I wanted to stay immutable.
This is a perfect reason to use a tuple in my book. A common and handy approach with objects persisted in databases is to have the persistent object track mutations, and make the attribute values themselves immutable. (I'm thinking ZODB in particular, but other persistence implementations support similar models.) Something I've often wanted to do is to construct a sequence (either list or tuple) based on both constant and variable portions: >>> source = [...some list of things...] >>> result = [a, b, *(x for x in source if condition)] -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> "Give me the luxuries of life and I will willingly do without the necessities." --Frank Lloyd Wright

On Fri, Apr 22, 2011 at 10:41 AM, Sturla Molden <sturla@molden.no> wrote:
I don' think that having this as part of the tuple/list constructor means that it "should be legal to write" everywhere else in the language. Would you also expect: f(a, b if c, d) == f(a, b, d) if c else f(a, d) if foo if bar: == if bar: if foo: return foo if bar == if bar: return foo I fail to see an advantage in these while I do see that it would be useful to write: (a if x, b if y, c if z, ...) If this works for tuple constructors, it *does* seem to me that it should work for lists, sets and dicts. That last one is sticky is it: { a if x : 1 } { a : 1 if x } or something else? Maybe tuples, lists and dicts are enough. Or maybe this just isn't useful enough. I'm +0.1 on this. --- Bruce *New! *Puzzazz newsletter: http://j.mp/puzzazz-news-2011-04 including April Fools! *New!** *Blog post: http://www.vroospeak.com Ironically, a glaring Google grammatical error

On 22/04/2011 19:44, Bruce Leban wrote:
Isn't the argument list of 'f' a tuple?
if foo if bar: == if bar: if foo:
return foo if bar == if bar: return foo
I'm having a bit of trouble parsing those...
The second one, because both the key and the value are conditional.
or something else? Maybe tuples, lists and dicts are enough. Or maybe this just isn't useful enough. I'm +0.1 on this.

I'm -1 on this. It looks like a syntax error for 'orange' if some_condition else 'another_color' -- --Guido van Rossum (python.org/~guido)

On Fri, Apr 22, 2011 at 12:00 PM, MRAB <python@mrabarnett.plus.com> wrote:
Sorry. I meant: if foo if bar: equivalent to: if (foo if bar): equivalent to: if bar: if foo: or more simply: if bar and foo: return foo if bar equivalent to: if bar: return foo which I hope make it clear why I don't like them.

On Fri, Apr 22, 2011 at 11:41 AM, Sturla Molden <sturla@molden.no> wrote:
More accurately: (a = 'orange') if cond and such conditional assignment statements don't exist in python.
The symmetry is with the following: a = 'orange' if cond else None Though the else clause with None would be implicit. This would result in "a" getting set to one or the other. However, the original idea implied that the "a" should not be be set at all if cond is true, as results in your example above with the if statement. I am not sure about the feasibility of adding conditional execution clauses to statements. And then embedding a related conditional composition in expression lists (for argument lists, etc.)... I'm not sure it's worth it. -eric
Sturla

Sturla Molden writes:
I like this interpretation:
You mean "spelling", right?
That's the only syntax proposed so far I like at all, but I still can't imagine a common need for it that isn't served well enough by the "tuple(comprehension)" spelling. Maybe the OP (or somebody) can expand a little on the use case for those of us lacking sufficient imagination?

Den 23.04.2011 21:36, skrev Westley Martínez:
No. This is a horrible idea.
Do you think so? ;-) The most "beautiful" thing with this syntax is this: After typing foo = 'orange' if cond or foo = 'orange' if cond else pass we don't know if accessing foo will raise a NameError or not (not without checking cond that is). And we all know what an uncaught exception might do (cf. Ariane 5). Sturla

My expectation would be that foo = 'orange' if cond would be equivalent to foo = 'orange' if cond else None Has this shorthand been considered before? It seems natural to me, and I do find myself writing "else None" a lot, but from a (cursory) search I couldn't find any discussion of it. The only downside that comes to mind: conditionals in comprehensions would look the same but have different semantics, i.e. [x for x in bar if f(x)] might lead one to expect that None is added to the list wherever the condition fails. Nathan On Sun, Apr 24, 2011 at 10:03 PM, Westley Martínez <anikom15@gmail.com> wrote:

On Sun, Apr 24, 2011 at 8:34 PM, Nathan Schneider <nathan@cmu.edu> wrote:
Also equivalent: foo = None if cond: foo = 'orange'
Zen violations I perceive: - Explicit is better than implicit. Is writing the extra 2 4-letter words, and thus being perfectly clear, really that burdensome? - Special cases aren't special enough to break the rules. - There should be one-- and preferably only one --obvious way to do it. Down the route of adding trivial syntax sugar lies Perl. - Errors should never pass silently. Something that is currently a syntax error (leaving off the `else foo` part of a ternary expression) would now be a valid expression, possibly leading to subtle typo-related bugs. Admittedly, how frequent this error is in practice is questionable. Please avoid top-posting in the future. Cheers, Chris -- http://blog.rebertia.com

On Fri, Apr 22, 2011 at 11:59 AM, cool-RR <cool-rr@cool-rr.com> wrote:
First note: If you can just remove an element in the middle and still have the same time of object, then logically it would be a list, not an array. But things that semantically are lists are indeed sometimes made array for performance reasons, so that's not a weird thing to do. Having said that, I don't think it's going to make it. Normally there's exactly one element between each pair of commas; if we're going to give up that, I'm not sure this is the best way to do it. As for other ways to do it, they are not as elegant but they certainly do exist: ('blue', 'red') + (('orange',) if some_condition else ()) + 'green' [c for c in ('blue', 'red', 'orange', 'green') if c != 'orange' or some_condition] -- André Engels, andreengels@gmail.com

On Fri, Apr 22, 2011 at 7:59 PM, cool-RR <cool-rr@cool-rr.com> wrote:
colours = 'blue red orange green'.split() if not some_conditions: colours.remove('orange') There are lots of options, but most of them start by not using a tuple for a variable length sequence of like items. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Fri, Apr 22, 2011 at 12:42 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
I see. It's about as elegant as the other suggestions. And it's pretty annoying to use a list when I really wanted to use a tuple. Yeah, I can convert it to a tuple at the end, but that's just making it more verbose. Ram.

On Fri, Apr 22, 2011 at 12:52 AM, Andre Engels <andreengels@gmail.com> wrote:
Exactly. Ignoring memory/performance differences, the semantic reason to use a tuple instead of a list is that you have group of things _and their ordering matters_. If you can arbitrarily omit some items in the sequence, it's not a tuple; it's a list. (Or maybe even a set.)

On Fri, Apr 22, 2011 at 12:52 PM, Andre Engels <andreengels@gmail.com>wrote:
"This kind of semantics"? What semantics did we have here except filtering items before putting them in the sequence? How is that more list-y than tuple-y? If I removed items *after* constructing the sequence, it'd be list-y, but since I want to do it *before* the construction, I think it doesn't make it list-y. I used a tuple in this case because it's something that I wanted to stay immutable. Ram.

On Fri, Apr 22, 2011 at 6:57 AM, cool-RR <cool-rr@cool-rr.com> wrote:
I used a tuple in this case because it's something that I wanted to stay immutable.
This is a perfect reason to use a tuple in my book. A common and handy approach with objects persisted in databases is to have the persistent object track mutations, and make the attribute values themselves immutable. (I'm thinking ZODB in particular, but other persistence implementations support similar models.) Something I've often wanted to do is to construct a sequence (either list or tuple) based on both constant and variable portions: >>> source = [...some list of things...] >>> result = [a, b, *(x for x in source if condition)] -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> "Give me the luxuries of life and I will willingly do without the necessities." --Frank Lloyd Wright

On Fri, Apr 22, 2011 at 10:41 AM, Sturla Molden <sturla@molden.no> wrote:
I don' think that having this as part of the tuple/list constructor means that it "should be legal to write" everywhere else in the language. Would you also expect: f(a, b if c, d) == f(a, b, d) if c else f(a, d) if foo if bar: == if bar: if foo: return foo if bar == if bar: return foo I fail to see an advantage in these while I do see that it would be useful to write: (a if x, b if y, c if z, ...) If this works for tuple constructors, it *does* seem to me that it should work for lists, sets and dicts. That last one is sticky is it: { a if x : 1 } { a : 1 if x } or something else? Maybe tuples, lists and dicts are enough. Or maybe this just isn't useful enough. I'm +0.1 on this. --- Bruce *New! *Puzzazz newsletter: http://j.mp/puzzazz-news-2011-04 including April Fools! *New!** *Blog post: http://www.vroospeak.com Ironically, a glaring Google grammatical error

On 22/04/2011 19:44, Bruce Leban wrote:
Isn't the argument list of 'f' a tuple?
if foo if bar: == if bar: if foo:
return foo if bar == if bar: return foo
I'm having a bit of trouble parsing those...
The second one, because both the key and the value are conditional.
or something else? Maybe tuples, lists and dicts are enough. Or maybe this just isn't useful enough. I'm +0.1 on this.

I'm -1 on this. It looks like a syntax error for 'orange' if some_condition else 'another_color' -- --Guido van Rossum (python.org/~guido)

On Fri, Apr 22, 2011 at 12:00 PM, MRAB <python@mrabarnett.plus.com> wrote:
Sorry. I meant: if foo if bar: equivalent to: if (foo if bar): equivalent to: if bar: if foo: or more simply: if bar and foo: return foo if bar equivalent to: if bar: return foo which I hope make it clear why I don't like them.

On Fri, Apr 22, 2011 at 11:41 AM, Sturla Molden <sturla@molden.no> wrote:
More accurately: (a = 'orange') if cond and such conditional assignment statements don't exist in python.
The symmetry is with the following: a = 'orange' if cond else None Though the else clause with None would be implicit. This would result in "a" getting set to one or the other. However, the original idea implied that the "a" should not be be set at all if cond is true, as results in your example above with the if statement. I am not sure about the feasibility of adding conditional execution clauses to statements. And then embedding a related conditional composition in expression lists (for argument lists, etc.)... I'm not sure it's worth it. -eric
Sturla

Sturla Molden writes:
I like this interpretation:
You mean "spelling", right?
That's the only syntax proposed so far I like at all, but I still can't imagine a common need for it that isn't served well enough by the "tuple(comprehension)" spelling. Maybe the OP (or somebody) can expand a little on the use case for those of us lacking sufficient imagination?

Den 23.04.2011 21:36, skrev Westley Martínez:
No. This is a horrible idea.
Do you think so? ;-) The most "beautiful" thing with this syntax is this: After typing foo = 'orange' if cond or foo = 'orange' if cond else pass we don't know if accessing foo will raise a NameError or not (not without checking cond that is). And we all know what an uncaught exception might do (cf. Ariane 5). Sturla

My expectation would be that foo = 'orange' if cond would be equivalent to foo = 'orange' if cond else None Has this shorthand been considered before? It seems natural to me, and I do find myself writing "else None" a lot, but from a (cursory) search I couldn't find any discussion of it. The only downside that comes to mind: conditionals in comprehensions would look the same but have different semantics, i.e. [x for x in bar if f(x)] might lead one to expect that None is added to the list wherever the condition fails. Nathan On Sun, Apr 24, 2011 at 10:03 PM, Westley Martínez <anikom15@gmail.com> wrote:

On Sun, Apr 24, 2011 at 8:34 PM, Nathan Schneider <nathan@cmu.edu> wrote:
Also equivalent: foo = None if cond: foo = 'orange'
Zen violations I perceive: - Explicit is better than implicit. Is writing the extra 2 4-letter words, and thus being perfectly clear, really that burdensome? - Special cases aren't special enough to break the rules. - There should be one-- and preferably only one --obvious way to do it. Down the route of adding trivial syntax sugar lies Perl. - Errors should never pass silently. Something that is currently a syntax error (leaving off the `else foo` part of a ternary expression) would now be a valid expression, possibly leading to subtle typo-related bugs. Admittedly, how frequent this error is in practice is questionable. Please avoid top-posting in the future. Cheers, Chris -- http://blog.rebertia.com
participants (14)
-
Andre Engels
-
Bruce Leban
-
Carl M. Johnson
-
Chris Rebert
-
cool-RR
-
Eric Snow
-
Fred Drake
-
Guido van Rossum
-
MRAB
-
Nathan Schneider
-
Nick Coghlan
-
Stephen J. Turnbull
-
Sturla Molden
-
Westley Martínez