Rocking the blogosphere
Apple Online Store

Python ternary operator

Today’s Python discovery:

Python doesn’t have the C style ?: ternary operator (e.g.: cond ? valueIfTrue : valueIfFalse).

But as of Python 2.5 it has a ternary operator with its own syntax: value_when_true if condition else value_when_false

For example:

>>> 'a' if 1 == 1 else 'b'
'a'
>>> 'a' if 1 == 0 else 'b'
'b'

This is actually clearer and more Pythonic than that ?:

Unfortunately, for Python versions < 2.5, you don’t have this. I’ve seen people use: (condition and [value_when_true] or [value_when_false])[0]

IMHO, this is clever – in a bad way. Yuck. Personally, I think I’d rather just do:


def if_cond_val1_else_val2(cond, val1, val2):
   if cond: return val1
   else: return val2

This adds 3 lines to your program (or 1 if you stick it in a module that you import from your programs) and won’t cause your colleagues to hate you.

Del.icio.us Digg Reddit Technorati

Possibly related posts

Comments

  1. drewp
    May 18th, 2008 | 11:54 pm

    Your ifelse function is substantially different when it comes to evaluating val1 and val2. Both of them are evaluated no matter what, which might be expensive.

    The and/or hack has almost-correct evaluation, but with the flaw that [value when false] gets chosen if [value when true] happens to be itself false. The other py2.4- version is like this:

    print “%d %s” % (x, ['egg', 'eggs'][x > 1])

    Too much evaluation, but mostly readable and without the subtle flaw of the and/or version.

  2. drewp
    May 18th, 2008 | 11:55 pm

    Oops- not “x > 1″ but “x != 1″. That way we can have “0 eggs”.

  3. ddcast
    May 21st, 2008 | 12:34 pm

    I think the ternary operator evaluation is better translated by this:

    eggs = 10
    result = (”not so many”,”more than a dozen”)[eggs>12]
    print result

    a little weird, but cleaner. i guess it is more natural to write tuples in pythonese…

  4. May 24th, 2008 | 3:40 am

    The >> True and ‘a’ or ‘b’
    ‘a’
    >>> False and ‘a’ or ‘b’
    ‘b’

  5. Luca Citi
    February 26th, 2009 | 8:44 am

    To drewp:

    “The and/or hack has almost-correct evaluation, but with the flaw that [value when false] gets chosen if [value when true] happens to be itself false.”

    If I understand your comment, it is inexact:
    [False] is True because it is a non-empty sequence

    (True and [False] or [22])[0]
    Out[1]: False

    This solution, albeit unreadable, is better than the other solutions because the [value when true] and [value when false]
    are only evaluated if the condition applies.

    In [5]: def p(x):
    print x
    return x
    …:

    In [8]: (True and [p(10)] or [p(22)])[0]
    10
    Out[8]: 10

    In [9]: [p(22), p(10)][True]
    22
    10
    Out[9]: 10

    Bye,
    Luca

Leave a reply

Apple Online Store
Apple Online Store