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.

8 comments to Python ternary operator

  • drewp

    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.

  • drewp

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

  • ddcast

    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…

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

  • Luca Citi

    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

  • I’m learning python right now.

    The more I see, the more I hate it, compared to Ruby.

    No “?:” … and the Python replacement is “better” ?!?!?

  • Elros Cyriatan

    @TJIC

    If we all chose languages based on the semantic operators available we’d all be programming in APL right now.

  • anon

    @TJIC seconded…. =/ it’s a torture working with this language…

Leave a Reply

  

  

  

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Categories

A sample text widget

Etiam pulvinar consectetur dolor sed malesuada. Ut convallis euismod dolor nec pretium. Nunc ut tristique massa.

Nam sodales mi vitae dolor ullamcorper et vulputate enim accumsan. Morbi orci magna, tincidunt vitae molestie nec, molestie at mi. Nulla nulla lorem, suscipit in posuere in, interdum non magna.