I’m annoyed with Python’s ternary operator

The ternary operator is a way to concisely say:
“If test, then a, else b“,
with the value of the statement being the value of a or b.

language how to say it
C test ? a : b
C++ test ? a : b
javaScript test ? a : b
Perl (not perl 6) test ? a : b
PHP test ? a : b
Ruby test ? a : b
Did I forget some language? probably
Python a if test else b
Why??

Why??

Ok. Now that I’ve written this post, I’ll remember it.

However, I just want to say…
On behalf of all of the other multiple-language programmers in the world, …
THIS IS LAME!!!

Update: No really, why??
Well, there are some reasonable reasons.
As noted in the comments, the Python version is more readable (at least in English).
And, to tell you the truth, if I ONLY were programming in Python, I’d probably prefer the Python version.
However, I don’t. I spend quite a bit of time in C++, Perl, PHP, and javaScript. And they ALL use the other form!

I understand the reasoning behind Python’s version.
I JUST DON’T AGREE WITH IT!

Rant over

Glad I’ve gotten that off my chest.

Comments

  1. Yup says

    Wouldn’t be the first time Python did something a little differently than the other popular languages. What’s this thing about whitespace? Having said that, it rolls off the tongue a little easier if you’re a native english speaker:

    Where are you going today?

    The beach if the weather is nice else I’ll just stay home.

  2. says

    Don’t use “test and a or b”, in some situations it doesn’t do what you think it does. Better would be to use “(test and [a] or [b])[0]“, but look at how hideous it is :)

    The ternary operator was put in exactly to help avoid ugly, low level code like this. Sure it’s different than other languages, but it’s not like you’ll have to look it up constantly. I remembered it the first time I saw it, which to me is a hallmark of good design, just like f.e. comprehensions.

  3. says

    My biggest nit with python’s ternary operator is that it is rather long when you’re trying to keep lines short (ie pep8 compliant). I’m a fan of short lines, but saving a few characters would be handy when you have some longer attribute / variable names.

  4. says

    All those languages essentially copied it from the granddaddy (i.e., C). Also, the ternary operator (properly called “conditional expressions”) are a relatively recent addition to Python (2.5) and from what I heard Guido resisted adding it. And the BDFL also didn’t copy other C features, e.g., increment/decrement operators, || and && for Boolean operations, switch/case statements, and not least: BRACES!!! (for scope, of course).

  5. says

    To be fair, I find the inconsistency to be a little jarring too. While a lot of python flows nicely this jars; and working across multiple languages is one of those oddities you need to remember for apparently no good reason.

  6. says

    The thing I like about Python (over, say, C++, as an example), is that the “small code” like this is more expressive – to my eye, anyway.

    “a if test else b” is closer to english than “test ? a : b”, and that can only be a good thing. Yes, it’s different to most other languages, but then, Python is better than most other languages as well!

  7. Simon Hibbs says

    Sorry but no, the ternary operator is a way to say something, not necessarily a way to concisely say it. You’re loading the argument by implying that terseness, as a desirable feature, has some special status over any others such as readability.

    Python’s syntax is informed by the insight that code is read a lot more often than it’s written, and there’s no guarantee that the reader happens to be familiar with any other programming language.

  8. says

    I know I am picking at straws but what about SQL? WHEN something THEN x ELSE y END

    I agree with people saying it rolls off the tongue better. I also program in multiple languages but this is something I can, quite happily, live with.

    • miyuki says

      This expression has different semantics: both expressions, b and c are evaluated. If ternary operator is used, only one of b or c (depending on value of a) gets evaluated.

    • TutNichtsZurSache says

      The problem isn’t operator precedence but associativity. I. e.
      a ? b : c ? d : e isn’t a ? b : (c ? d : e) but (a ? b : c) ? d : e.

  9. Bryan says

    CoffeeScript also has a screwed-up ternary “operator”. foo = if x > y then “cake” else “pie”
    SO much more typing than JavaScript or most other languages…

  10. Don X says

    Almost every time I hear people use “if” in English, it is always before anything else. If x then y else z comes from that, x ? y : z is just a natural short way of saying the same thing.

    “If it is not raining today, I go outside.”
    “I go outside, if it is not raining today.”

    Which one is easier to understand? I see the first used much more often than the second, and the second makes it hard to see that it is a conditional until after you already hear/read everything else, so it is more confusing. Especially if the statement is very long.

  11. miyuki says

    >Did I forget some language? – probably
    In lua there is an interesting idiom for ternary operator. Logical operators are “short-circuited” (this means that the expression “true and x” will return the value of x, even if x is not boolean), that’s why ternary operator looks like this:
    “test and a or b”

  12. eplimish says

    I wouldn’t say CoffeeScript is screwed – it’s just the consequence of allowing the if-the-else construct as an expression. Scala also allows this as does Ruby (although Ruby also has the test ? true_v : false_v expression – but then Ruby also evaluates everything as true except nil and false – including 0, 0.0 and empty collections – you want uniformity?).

    Given the lack of new semantics, it is obvious to a newbie programmer what is going on, although it does allow the possibility of nightmarish nested if-then-(if-then-else)-else-(if-then-else) tangles. I have had in the past a programmer come to me and say “I haven’t a clue what is meant by this!!” when confronted with the C style ternary op – but that was before widespread availability of the Internet. And certain managers I have know went apoplectic at the use of the C ternary op to the point of banning it in coding standards completely – but generally because it could be abused the same way as if-then-else as an expression.

    I guess BDFL did not want to introduce new terms into the language syntax – if and else were already there, while at the same time avoiding the pitfalls of test and not_always_true_value or default_value. Also you would have to be crazy to abuse the syntax, which although awkward, kind of suppresses the following abuses even in the most operator-obsessive programmer.

    ####
    from itertools import combinations_with_replacement as cwr
    def foo(a, b, c):
    return (1 if b else 2) if a else (3 if c else 4) # ugh

    for t in cwr((False, True), 3):
    print “foo{} :-> {}”.format(t, foo(*t))
    ####

    It works! But it does introduce a certain amount of self policing. But you would see it a lot more if BDFL had allowed:

    #### won’t work
    def foo(a, b, c):
    return a? (b? 1: 2) : (c? 3: 4) # I knew quite a few people who liked to do this
    ####

    or even

    #### won’t work either
    def foo(a, b, c):
    return if a: (if b: 1 else: 2) else: (if c: 3 else: 4) # probably wrecks the parser!!!
    ####

    And that’s what he was on about with a language that insisted on indentation in the first place I imagine.

  13. Riku says

    Python’s ternary if may be a little bit annoying and verbose, but unlike the commonly used ?: operator, Python’s ternary conditional expression is composable, so you may have more than one condition like this:

    print(‘\n’.join(
    ‘FizzBuzz’ if x%5==0 and x%3==0
    else ‘Fizz’ if x%3==0
    else ‘Buzz’ if x%5==0
    else str(x)
    for x in range(1, 101)))

    Doing the same with C-style ?: operator will be very hard to read.

    • MrG says

      for (int x=1; x<101; x++) {
      string s = (x%5==0 and x%3==0) ? "FizBuzz" :
      (x%3==0) ? "Fizz" :
      (x%5==0) ? "Buzz" :
      to_string(x);
      cout << s << endl;
      }

      Range/list objects are python's forte, but the actual ternary op code looks a bit easier to read in C++ to me… At worst, it looks no less clear than the python equivalent..

      Trying to be as impartial as possible when looking at this… I love both languages..

Leave a Reply