[Python-Dev] Adding a conditional expression in Py3.0

Ron Adam rrr at ronadam.com
Wed Sep 21 17:39:45 CEST 2005


Nick Coghlan wrote:

> Greg Ewing wrote:
>>One nice thing about "x if b else y" is that it
>>chains without needing any more keywords:
>>
>>   x if b else y if c else z
>>
>>But if you require parens, it's not so nice:
>>
>>   (x if b else (y if c else z))

> If Guido chose this form, I would expect the chaining to work like chaining 
> loops in a generator expression, with parentheses being required around the 
> whole thing, rather than around each element in the chain:
> 
>      (x if b else y if c else z)
> 
> The point being that the result of the conditional expression is exactly one 
> of the options included in the expression, so only one set of parentheses is 
> required.


Either a or b could be a nested expression so it's important that it be 
readable in both cases.

(a if e then b)
((a1 if e1 then b1) if e then b)
(a if e then (a2 if e2 then b2))
((a1 if e1 then b1) if e then (a2 if e2 then b2))


Without parentheses...

(a if e then b)
(a1 if e1 then b1 if e then b)
(a if e then a2 if e2 then b2)
(a1 if e1 then b1 if e then a2 if e2 then b2)

I think the parentheses version is clearer. To me it's not as easy to 
picture what will happen when the condition is in the middle of the 
expression.

Also in the above, is e1 evaluated before e?  That would mean the result 
of e1 (a1 or b1) is thrown away if e if false.


So looking at a few alternatives ...

(e ? a : b)
(e ? (e1 ? a1 : b1) : b)
(e ? a : (e2 ? a2 : b2))
(e ? (e1 ? a1 : b1) : (e2 ? a2 : b2))

This better represents a decision tree I think. Each comparison gives 
one of two possible results which may be another comparison.

Using keywords instead...

(if e, a else b)
(if e, (if e1, a1 else b1) else b)
(if e, a else (if e2, a2 else b2))
(if e, (if e1, a1 else b1) else (if e2, a2 else b2))

(if e then a else b)
(if e then (if e1 then a1 else b1) else b)
(if e then a else (if e2 then a2 else b2))
(if e then (if e1 then a1 else b1) else (if e2 then a2 else b2))


or... possibly...

(e selects a else b)
(e selects (e1 selects a1 else b1) else b)
(e selects a else (e2 selects a2 else b2))
(e selects (e1 selects a1 else b1) else (e2 selects a2 else b2))

I like this one, but maybe a shorter verb would be nice.

Other possible words might be "gives", "chooses" or "picks".


With the (e?a:b) syntax, I tend to want to switch the '?' and ':' here 
so that the colon is more consistent with how Python uses it.

(e: a ? b)
(e: (e1: a1 ? b1) ? b)
(e: a ? (e2: a2 ? b2))
(e: (e1: a1 ? b1) ? (e2: a2 ? b2))

That may be more confusing to those who are use to 'C', but clearer to 
those who use Python as their main programming language.  The '?' 
becomes an 'else' which might be useful in other expressions.

Without the colon ...

(e selects a ? b)
(e selects (e1 selects a1 ? b1) ? b)
(e selects a ? (e2 selects a2 ? b2))
(e selects (e1 selects a1 ? b1) ? (e2 selects a2 ? b2))



Or if e evaluates an integer... :-)

(e selects a, b, c, ...)

I think this would be quite useful and would work perfectly well with 
boolean expressions as well.  The advantage here is that a,b,c etc.. 
would not be pre evaluated as they are when you use a list or dictionary.

(e selects a, b)
(e selects (e1 selects a1, b1), b)
(e selects a, (e2 selects a2, b2))
(e selects (e1 selects a1, b1), (e2 selects a2, b2))

( e selects (e1 selects a1, b1),
             (e2 selects a2, b2),
             (e3 selects a3, b3) )

Being able to have more than two alternative may reduce the need to nest 
or chain them in some cases.

A variation might be to have negative index's pick from the far end just 
as list index's do.

This would be my choice although I wasn't thinking of it when I started 
this reply. ;-)

Cheers,
Ron



























More information about the Python-Dev mailing list