Towards a more Pythonic "Ternary Operator"

sismex01 at hebmex.com sismex01 at hebmex.com
Tue Mar 4 10:09:52 EST 2003


> From: Clark C. Evans [mailto:cce at clarkevans.com]
> Sent: Tuesday, March 04, 2003 7:06 AM
> 
>      if a == X:
>         b = Q
>      elif a == Y:
>         b = R
>      else:
>         b = S
> 
> In this case, not only is 'b = ' duplicated three times,
> but 'a ==' is duplicated twice.  These two can be combined
> into the select/case pattern:
> 
> b = select a:
>       case X: Q
>       case Y: R
>       else:   S
> 

Yes, there is a lot of duplicated "text" in the first
case, and the second case corrects that.  But you don't
need new syntax to be able to make it better, you already
have dictionaries:

 b = { Q:X, R:Y }.get(a,S)

At least to me, it's a lot more readable, doesn't involve
new syntax, and can grow to a larget amount of options
if needed.

And it isn't limited to constant expressions inside the
dictionary, as this IDLE session demonstrates:

>>> a, A = "a", "Peter"
>>> b, B = "b", "John"
>>> c, C = "c", "Ernest"
>>> default = "Spanish Inquisition"
>>> def chooser(choice):
	global a, A, b, B, c, C, default
	return { a:A, b:B, c:C }.get(choice, default)

>>> print chooser("a")
Peter
>>> print chooser("c")
Ernest
>>> print chooser("x")
Spanish Inquisition
>>> print chooser("b")
John
>>> print chooser("John")
Spanish Inquisition
>>> B = "Ironman"
>>> print chooser("b")
Ironman
>>> A = "Raquel Welch"
>>> C = "Ozzy Osbourne"
>>> default = "Eric Idle"
>>> print chooser("a")
Raquel Welch
>>> print chooser("d")
Eric Idle
>>> print chooser("c")
Ozzy Osbourne
>>> c = "zz"
>>> print chooser("zz")
Ozzy Osbourne
>>> 


The "need" for a ternary operator in many occasions is
created by not knowing the "correct" pythonic construction
which expresses that which you need to do.  Python's
interactive nature helps you explore all that.

Ternary operators are good to select between two (and
let's keep it at two) expressions which might have
(severe?) side-effects, there lies the need for short-
circuiting.

In the above example, imagine evaluating A, B or C could
have side-effects; in that case, upon constructing the
selection dictionary, all side-effects would have been
triggered, so this construction would be no good.  It
could be adapted, by changing the function chooser()
like so:

>>> def chooser(option):
      try:
        return { a:lambda:A, 
                 b:lambda:B,
                 c:lambda:C }[option]()
      except KeyError:
        return default

It becomes a bit more complex, but still quite simple.

-gustavo





More information about the Python-list mailing list