Towards a more Pythonic "Ternary Operator"

John Roth johnroth at ameritech.net
Tue Mar 4 12:46:00 CET 2003


Interesting. I'm not sure what to make of it, but it
has one huge advantage over the current flameage:
you're actually thinking!

Good work.

John Roth

"Clark C. Evans" <cce at clarkevans.com> wrote in message
news:mailman.1046774818.32264.python-list at python.org...
> After looking over my code some, I found that where
> I thought I needed a terinary operator, I ended
> up taking one of two paths:
>
>   exit = { 0: 'no exit',
>            1: 'a door' }.get(quantity,
>           '%s doors' % quantity)
>
> Or, the more 'obvious' ...
>
>   if   0 == quantity:  exit = 'no exit'
>   elif 1 == quantity: exit = 'a door'
>   else: exit = '%s doors' % quantity
>
> The first construct has two advantages over the more 'obvious'
> solution:
>
>   1. It's clear that I'm making an assignment to exit
>   2. I don't have to duplicate the ugly '== quantity'
>      each time.
>
> However, the first construct brings with it two problems:
>
>   1. The 'else' case is kinda ugly.
>   2. It doesn't short-circut cleanly, to have the short-circut
>      behavior you need to use lambda's as the mapping values
>      and then invoke the result...
>
> So, if you asked me, what I'd like is a hybrid of the two options
> above, a nicer-looking short-circuting in-line mapping:
>
>   exit = select quantity
>            case 0: 'no exit'
>            case 1: 'a door'
>            else: '%s doors' % quantity
>
>   #NOTE: new lines/indentation is mandatory in this proposal
>
> IMHO, the other options in the survey are quite clean
> when you look at it this way:
>
>   data = select hasattr(s,'open')
>            case true: s.readlines()
>            else: s.split()
>
>   z = 1.0 + select abs(z) < .0001
>               case true: 0
>               else: z
>
>   t = v[index] = select t <= 0
>                    case true: (t-1.0)
>                    else: -sigma / (t + 1.0)
>
>   return select len(s) < 10
>            case true: linsort(s)
>            else: qsort(s)
>
> ...
>
> The other advantage of this mechanism is that the
> semantics could be made a bit more flexible by requiring
> the case item to be a predicate -- a boolean function
> with one argument, the item being selected upon.  Thus,
>
> z = 1.0 + select abs(z)
>             case lt(.0001): 0
>             case gt(.5): .5
>             else: -sigma / (t + 1.0)
>
> score = select die
>            case 1: -2
>            case 2: -1
>            case between(3,4): 0
>            case 5: +1
>            case 6: +2
>            else:
>                raise "invalid die roll %d " % roll
>
> Since the items 1,2,5,6 arn't predicates, then the
> "equal" predicate is assumed.
>
> Now... _this_ I would really find useful.
>
> Best,
>
> Clark
>






More information about the Python-list mailing list