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

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

(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.

(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

Cheers,
Ron

```