views:

8452

answers:

7

I was under the impression that Python had a ternary operator...

But then I did some research,

Not enough to find out for sure though

Thought I'd ask the professionals ;)

+50  A: 

Yes, it has been relatively recently added (in 2.5 IIRC). It's frowned upon by many pythonistas, so use with caution. The syntax is:

a if b else c

First b is evaluated, then either a or c is returned based on the truth value of b; if b evaluates to true a is returned, else c is returned.

For example:

>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'

Official docs here.

Vinko Vrsalovic
Why is this frowned on?
iconoplast
The operator itself is not really frowned upon. It's just the form that bugs some people with a C-something background. They where expecting the conditional to be first, but van Rossum chose to put it in the middle. I actually find it cute. ^_^
efotinis
I've found that many Pythonistas really dislike the operator and prefer instead an if-else construct, claiming that the style guide says so. I haven't seen it there though.
Vinko Vrsalovic
I think it is really pythonian, because if you read it out loud, you (almost) say what you mean "x = 4 if b>8 else 9" -> "x will be 4 if b is greater than 8 otherwise 9"
BlackShift
cause it goes against the flow of thoughts. It reads out nice but in your mind, you think of the condition first and then the effects
Xster
@Xster: No I don't.
Longpoke
@Xster: Quite true, I do think that way.
Vuntic
+5  A: 

From http://www.python.org/doc/2.5.2/ref/Booleans.html

The expression

x if C else y

first evaluates C (not x); if C is true, x is evaluated and its value is returned; otherwise, y is evaluated and its value is returned. New in version 2.5.

Michael Burr
+7  A: 

For versions prior to 2.5, there's the trick:

test and true_value or false_value

This feels more hacky than the new A if B else C syntax mentioned elsewhere, and is generally considered to be a Bad Thing. Although it does have the benefit of evaluating expressions left to right, which is clearer in my opinion.

Alabaster Codify
What happens if "true value" evaluates to False (e.g. is None)?
Roberto Liffredo
Then you get false_value
recursive
The remedy is to use (test and [true_value] or [false_value])[0], which avoids this trap.
ThomasH
+4  A: 

"Dive into Python" the book lays out the trick and its pitfalls very clearly here. It also provides reference for safe implementation of ternary operator in Python here

JV
+9  A: 

You can index into a tuple:

(falseValue, trueValue)[test]

test needs to return True or false. It might be safer to always implement as:

(falseValue, trueValue)[test == True]
landon9720
voted up because still not everyone uses python 2.4
BlackShift
* some people still use 2.4
BlackShift
+1  A: 

@up:

Unfortunately, the

(falseValue, trueValue)[test]

solution don't have short-circuit behaviour, thus both falseValue and trueValue are evaluated regardless of the condition. This could be suboptimal or even buggy (i.e. both trueValue and falseValue could be methods and have side-effects).

Some solution to this would be

(falseValue, trueValue)[test]()

(execution delayed until the winner is known ;)), but it introduces inconsistency between callable and non-callable objects. In addition, it don't solves the case when using properties.

And so the story goes - choosing between 3 mentioned solutions is trade-off between having the short-circuit feature, using at least python2.5 (2.4?) (IMHO no problem any more) and not beeing prone to "trueValue-evaluates-to-false" errors.

gorsky
+1  A: 

expression1 if condition else expression2

>>> a = 1
>>> b = 2
>>> c = 0 if a > b else 1 
1
>>> c = 0 if a > b else 1 if a < b else -1
1
Simon Zimmermann
What's the difference between this and the top answer?
KennyTM
This one emphasizes the primary intent of the ternary operator: value selection. It also shows that more than one ternary can be chained together into a single expression.
Roy Tinker