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