conditional expressions

Terry Reedy tjreedy at udel.edu
Mon Sep 30 13:34:16 EDT 2002


"Alex Martelli" <aleax at aleax.it> wrote in message
news:oOZl9.162526$ub2.3640508 at news1.tin.it...
> Terry Reedy wrote:
> > If b is a non-null constant, there is no such risk.  Consider
>
> If it's a constant, you don't need short-circuiting!

If the alternative is *also* a constant, correct; indexing works fine.
If it is not, the short-cicuiting of 'or' may be crucial.  Example:
y==0 and NAN or x/y.  Reversing the test and alternatives won't work
if x might be 0.

(Yes, I might prefer to let x/y raise an exception. Or I might write a
function fdiv(x,y).   But for one time use or in the innermost loop of
a calculation, the quickly written condtional might be just what I
want.)

> def plur(*ns):
>     for n in ns:
>         yield n
>         yield 's'[n!=1:]

Using the conditional in a slice rather than an index to get a null
alternative is a cute trick I had not thought of.

Posting a concrete usage for and/or an pulled out nice alternatives
from 3 or 4 different people.  Let's try a couple of others:

In the middle of an expression, I want the 7th or 3rd item in seq
depending on <cond> (an expression yielding 0 or 1).  Five
alternatives (where ... ... is usage context):

...seq[<cond> and 2 or 6]...
...seq[(6,2)[<cond>]]...
...seq[6-4*<cond>]...
...seq[2+(not<cond>)*4]...  # this generalizes better -- see below

if <cond>: tem = 2
else         : tem = 6
...tem...

Anything else?  Among these four I would probably prefer the first,
but don't care if others choose elsewise.  Now for a three-way split:

...seq[<cond1> and 2 or <cond2> and 6 or 3]... # abbreviating

if     <cond1>: tem = 2
elif  <cond2>: tem = 6
else               : tem = 3
...tem...

Assuming <cond2> doesn't need short-cicuiting when <cond1> is true and
doesn't take significantly long to calculate when not needed, we can
again substitute tuple indexing (or direct index calculation), but I
think it would take most people longer to correctly write any
alternative below, at least the first time.  Is it worth it to avoid
the easy-to-write and easy-to-read-and-understand conditional
expression?  Not for me, I think, but others are welcome to differ.

...seq[((3,6)[<cond2>],2)[<cond1>]]... #or
...seq[(3,6,2,2)[2*<cond1> + <cond>]]...
...seq[2 + (not<cond1>)*(1+3*<cond2>)]...
...seq[2 + (not<cond1>)*(4-(not<cond2>)*3)]...

Terry J. Reedy






More information about the Python-list mailing list