8109
1

32 Answers32

9336

Yes, it wasadded in version 2.5. The expression syntax is:

a if condition else b

Firstcondition is evaluated, then exactly one of eithera orb is evaluated and returned based on theBoolean value ofcondition. Ifcondition evaluates toTrue, thena is evaluated and returned butb is ignored, or else whenb is evaluated and returned buta is ignored.

This allows short-circuiting because whencondition is true onlya is evaluated andb is not evaluated at all, but whencondition is false onlyb is evaluated anda is not evaluated at all.

For example:

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

Note that conditionals are anexpression, not astatement. This means you can't usestatements such aspass, or assignments with= (or "augmented" assignments like+=), within a conditionalexpression:

>>> pass if False else pass  File "<stdin>", line 1    pass if False else pass         ^SyntaxError: invalid syntax>>> # Python parses this as `x = (1 if False else y) = 2`>>> # The `(1 if False else x)` part is actually valid, but>>> # it can't be on the left-hand side of `=`.>>> x = 1 if False else y = 2  File "<stdin>", line 1SyntaxError: cannot assign to conditional expression>>> # If we parenthesize it instead...>>> (x = 1) if False else (y = 2)  File "<stdin>", line 1    (x = 1) if False else (y = 2)       ^SyntaxError: invalid syntax

(In 3.8 and above, the:= "walrus" operator allows simple assignment of valuesas an expression, which is then compatible with this syntax. But please don't write code like that; it will quickly become very difficult to understand.)

Similarly, because it is an expression, theelse part ismandatory:

# Invalid syntax: we didn't specify what the value should be if the # condition isn't met. It doesn't matter if we can verify that# ahead of time.a if True

You can, however, use conditional expressions to assign a variable like so:

x = a if True else b

Or for example to return a value:

# Of course we should just use the standard library `max`;# this is just for demonstration purposes.def my_max(a, b):    return a if a > b else b

Think of the conditional expression as switching between two values. We can use it when we are in a 'one value or another' situation, where we willdo the same thing with the result, regardless of whether the condition is met. We use the expression to compute the value, and then do something with it. If you need todo something different depending on the condition, then use a normalifstatement instead.


Keep in mind that it's frowned upon by some Pythonistas for several reasons:

  • The order of the arguments is different from those of the classiccondition ? a : b ternary operator from many other languages (such asC,C++,Go,Perl,Ruby,Java,JavaScript, etc.), which may lead to bugs when people unfamiliar with Python's "surprising" behaviour use it (they may reverse the argument order).
  • Some find it "unwieldy", since it goes contrary to the normal flow of thought (thinking of the condition first and then the effects).
  • Stylistic reasons. (Although the 'inlineif' can bereally useful, and make your script more concise, it really does complicate your code)

If you're having trouble remembering the order, then remember that when read aloud, you (almost) say what you mean. For example,x = 4 if b > 8 else 9 is read aloud asx will be 4 if b is greater than 8 otherwise 9.

Official documentation:

Karl Knechtel's user avatar
Karl Knechtel
61.4k14 gold badges132 silver badges193 bronze badges
answeredDec 27, 2008 at 8:44
Vinko Vrsalovic's user avatar
Sign up to request clarification or add additional context in comments.

23 Comments

The order may seems strange for coders howeverf(x) = |x| = x if x > 0 else -x sounds very natural to mathematicians. You may also understand it as do A in most case, except when C then you should do B instead...
Be careful with order of operations when using this. For example, the linez = 3 + x if x < y else y. Ifx=2 andy=1, you might expect that to yield 4, but it would actually yield 1.z = 3 + (x if x > y else y) is the correct usage.
The point was if you want to perform additional evaluationsafter the conditional is evaluated, like adding a value to the result, you'll either need to add the additional expression to both sides (z = 3 + x if x < y else 3 + y), or group the conditional (z = 3 + (x if x < y else y) orz = (x if x < y else y) + 3)
@MrGeek, I see what you mean, so you would basically be nesting the operations: ` "foo" if Bool else ("bar" if Bool else "foobar") `
Programmers need precise correct formulation even more than mathematician, because in mathematics there is always a resort to underlying concepts. A convincing argument is the % operator, mimicking the way "mod" is used in math would have been a disaster. So no, I don't accept your argument. It is like adhering to imperial units. Groetjes Albert
|
1027

You can index into a tuple:

(falseValue, trueValue)[test]

test needs to returnTrue orFalse.
It might be safer to always implement it as:

(falseValue, trueValue)[test == True]

or you can use the built-inbool() to assure aBoolean value:

(falseValue, trueValue)[bool(<expression>)]
jesterjunk's user avatar
jesterjunk
2,48224 silver badges20 bronze badges
answeredJan 22, 2009 at 18:58
Landon Kuhn's user avatar

12 Comments

Note that this one always evaluates everything, whereas the if/else construct only evaluates the winning expression.
(lambda: print("a"), lambda: print("b"))[test==true]()
It should be noted that what's within the[]s can be an arbitrary expression. Also, for safety you can explicitly test for truthiness by writing[bool(<expression>)]. Thebool() function has been around since v2.2.1.
I've done a similar trick -- only once or twice, but done it -- by indexing into a dictionary withTrue andFalse as the keys:{True:trueValue, False:falseValue}[test] I don't know whether this is any less efficient, but it does at least avoid the whole "elegant" vs. "ugly" debate. There's no ambiguity that you're dealing with a boolean rather than an int.
|
449

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

[expression] and [on_true] or [on_false]

It can give wrong results whenon_true has a false Boolean value.1

Although it does have the benefit of evaluating expressions left to right, which is clearer in my opinion.

1.Is there an equivalent of C’s ”?:” ternary operator?

Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredDec 27, 2008 at 10:48
James Brady's user avatar

7 Comments

The remedy is to use (test and [true_value] or [false_value])[0], which avoids this trap.
Ternary operator usually executes faster(sometimes by 10-25%).
@volcano Do you have source for me?
@OrangeTuxHere's the disassembled code. Using the method ThomasH suggested would be even slower.
Why you say "for versions prior to 2.5"? This works under 3.12.1 for me.
|
373

<expression 1>if<condition>else<expression 2>

a = 1b = 21 if a > b else -1 # Output is -11 if a > b else -1 if a < b else 0# Output is -1
Ed The ''Pro'''s user avatar
Ed The ''Pro''
95912 silver badges23 bronze badges
answeredMay 27, 2010 at 7:56
Simon Klee's user avatar

4 Comments

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.
@Craig , I agree, but it's also helpful to know what will happen when there are no parentheses. In real code, I too would tend to insert explicit parens.
Use:return 3 if t > 10 else t/2
you can do1 if a > b else -1 if a < b else 0 ::::::::::::::: ::::::::::::: ::::::::::::: ::::::::::::: or you can do just(-(a != b))**(a <= b) ::: a branch free ternary free math expression that will always yield the signum of-1, 0, or 1 without having to hard code any of the 3 outcomes at all
214

Fromthe documentation:

Conditional expressions (sometimes called a “ternary operator”) have the lowest priority of all Python operations.

The expressionx if C else y first evaluates the condition,C (not x); ifC is true,x is evaluated and its value is returned; otherwise,y is evaluated and its value is returned.

SeePEP 308 for more details about conditional expressions.

New since version 2.5.

jesterjunk's user avatar
jesterjunk
2,48224 silver badges20 bronze badges
answeredDec 27, 2008 at 8:44
Michael Burr's user avatar

Comments

193

An operator for a conditional expression in Python was added in 2006 as part ofPython Enhancement Proposal 308. Its form differs from common?: operator and it looks like this:

<expression1> if <condition> else <expression2>

which is equivalent to:

if <condition>: <expression1> else: <expression2>

Here is an example:

result = x if a > b else y

Another syntax which can be used (compatible with versions before 2.5):

result = (lambda:y, lambda:x)[a > b]()

where operands arelazily evaluated.

Another way is by indexing a tuple (which isn't consistent with the conditional operator of most other languages):

result = (y, x)[a > b]

or explicitly constructed dictionary:

result = {True: x, False: y}[a > b]

Another (less reliable), but simpler method is to useand andor operators:

result = (a > b) and x or y

however this won't work ifx would beFalse.

A possible workaround is to makex andy lists or tuples as in the following:

result = ((a > b) and [x] or [y])[0]

or:

result = ((a > b) and (x,) or (y,))[0]

If you're working with dictionaries, instead of using a ternary conditional, you can take advantage ofget(key, default), for example:

shell = os.environ.get('SHELL', "/bin/sh")

Source:?: in Python at Wikipedia

Marc Sances's user avatar
Marc Sances
2,6441 gold badge22 silver badges38 bronze badges
answeredMay 5, 2015 at 12:00
kenorb's user avatar

3 Comments

result = {1: x, 0: y}[a > b] is another possible variant (True andFalse are actually integers with values1 and0)
It's wired that Expression comes first before the condition. After some practice, I can remember it now.
if <condition>: <expression1> else: <expression2> is not valid syntax in either Python 2.7 or 3.x. It needs to be on two lines, and it doesn't return the winning expression, it only evaluates it. So it's a long way from being equivalent to<expression1> if <condition> else <expression2>. It would be more accurate to say thatx = <expression1> if <condition> else <expression2> is equivalent toif <condition>: x = <expression1> newlineelse: x = <expression2>.
128

Unfortunately, the

(falseValue, trueValue)[test]

solution doesn't have short-circuit behaviour; thus bothfalseValue andtrueValue are evaluated regardless of the condition. This could be suboptimal or even buggy (i.e. bothtrueValue andfalseValue could be methods and have side effects).

One solution to this would be

(lambda: falseValue, lambda: trueValue)[test]()

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

And so the story goes - choosing between three mentioned solutions is a trade-off between having the short-circuit feature, using at least Python 2.5 (IMHO, not a problem anymore) and not being prone to "trueValue-evaluates-to-false" errors.

Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredDec 6, 2009 at 11:51
gorsky's user avatar

2 Comments

While the tuple of lambdas trick works, it takes roughly 3x as long as the ternary operator. It's only likely to be a reasonable idea if it can replace a long chain ofif else if.
this is so unreadable compared with the ternary operator
91

For Python 2.5 and newer there is a specific syntax:

[on_true] if [cond] else [on_false]

In older Pythons, a ternary operator is not implemented but it's possible to simulate it.

cond and on_true or on_false

Though there is a potential problem, which is ifcond evaluates toTrue andon_true evaluates toFalse thenon_false is returned instead ofon_true. If you want this behaviour the method is OK, otherwise use this:

{True: on_true, False: on_false}[cond is True] # is True, not == True

which can be wrapped by:

def q(cond, on_true, on_false)    return {True: on_true, False: on_false}[cond is True]

and used this way:

q(cond, on_true, on_false)

It is compatible with all Python versions.

enslaved_programmer's user avatar
enslaved_programmer
2962 silver badges12 bronze badges
answeredApr 25, 2012 at 11:40
Paolo's user avatar

2 Comments

The behaviour is not identical -q("blob", on_true, on_false) returnson_false, whereason_true if cond else on_false returnson_true. A workaround is to replacecond withcond is not None in these cases, although that is not a perfect solution.
Why notbool(cond) instead ofcond is True? The former checks the truthiness ofcond, the latter checks for pointer-equality with theTrue object. As highlighted by @AndrewCecil,"blob" is truthy but itis not True.
63

You might often find

cond and on_true or on_false

but this leads to a problem when on_true == 0

>>> x = 0>>> print x == 0 and 0 or 11>>> x = 1>>> print x == 0 and 0 or 11

Where you would expect this result for a normal ternary operator:

>>> x = 0>>> print 0 if x == 0 else 10>>> x = 1>>> print 0 if x == 0 else 11
Javad's user avatar
Javad
2,1333 gold badges16 silver badges25 bronze badges
answeredJan 14, 2013 at 15:56
Benoit Bertholon's user avatar

Comments

60

Does Python have a ternary conditional operator?

Yes. From thegrammar file:

test: or_test ['if' or_test 'else' test] | lambdef

The part of interest is:

or_test ['if' or_test 'else' test]

So, a ternary conditional operation is of the form:

expression1 if expression2 else expression3

expression3 will be lazily evaluated (that is, evaluated only ifexpression2 is false in a boolean context). And because of the recursive definition, you can chain them indefinitely (though it may considered bad style.)

expression1 if expression2 else expression3 if expression4 else expression5 # and so on

A note on usage:

Note that everyif must be followed with anelse. People learning list comprehensions and generator expressions may find this to be a difficult lesson to learn - the following will not work, as Python expects a third expression for an else:

[expression1 if expression2 for element in iterable]#                          ^-- need an else here

which raises aSyntaxError: invalid syntax.So the above is either an incomplete piece of logic (perhaps the user expects a no-op in the false condition) or what may be intended is to useexpression2 as a filter - notes that the following is legal Python:

[expression1 for element in iterable if expression2]

expression2 works as a filter for the list comprehension, and isnot a ternary conditional operator.

Alternative syntax for a more narrow case:

You may find it somewhat painful to write the following:

expression1 if expression1 else expression2

expression1 will have to be evaluated twice with the above usage. It can limit redundancy if it is simply a local variable. However, a common and performant Pythonic idiom for this use-case is to useor's shortcutting behavior:

expression1 or expression2

which is equivalent in semantics. Note that some style-guides may limit this usage on the grounds of clarity - it does pack a lot of meaning into very little syntax.

Javad's user avatar
Javad
2,1333 gold badges16 silver badges25 bronze badges
answeredNov 17, 2015 at 19:14
Aaron Hall's user avatar

4 Comments

expression1 or expression2 being similar and with the same drawbacks/positives asexpression1 || expression2 in javascript
Thanks, @selurvedu - it can be confusing until you get it straight. I learned the hard way, so your way might not be as hard. ;) Using if without the else, at the end of a generator expression or list comprehension will filter the iterable. In the front, it's a ternary conditional operation, and requires the else. Cheers!!
@AaronHall Although your use of metasyntacticexpressionN for all instances is consistent, it might be easier to understand with naming that distinguished the conditional test expression from the two result expressions; eg,result1 if condition else result2. This is especially evident when nesting (aka chaining):result1 if condition1 else result2 if condition2 else result3. See how much better that reads this way?
@tchrist thanks for the review - if you look at the revision history, this post currently has two revisions. Most of my other answers, especially the top ones, have been revisited again and again. This answer never gets my attention because the community wiki status gives me no credit for the content, and so I never see any votes on it. As I don't really have time for an edit on this right now, frog knows when it will come to my attention again in the future. I can see you've edited the top answer, so feel free to borrow/quote my material from this post in that one (and cite me if apropos!)
56

One of the alternatives to Python'sconditional expression

"yes" if boolean else "no"

is the following:

{True: "yes", False: "no"}[boolean]

which has the following nice extension:

{True: "yes", False: "no", None: "maybe"}[boolean_or_none]

The shortest alternative remains

("no", "yes")[boolean]

which works becauseissubclass(bool, int).

Careful, though: the alternative to

yes() if boolean else no()

isnot

(no(), yes())[boolean]  # bad: BOTH no() and yes() are called

but

(no, yes)[boolean]()

This works fine as long asno andyes are to be called with exactly the same parameters. If they are not, like in

yes("ok") if boolean else no()  # (1)

or in

yes("ok") if boolean else no("sorry")  # (2)

then a similar alternative either does not exist (1) or is hardly viable (2). (In rare cases, depending on the context, something like

msg = ("sorry", "ok")[boolean](no, yes)[boolean](msg)

could make sense.)

Thanks to Radek Rojík for his comment


Addendum:

A special case of boolean indexing is when you need a single character. E.g.:

sign = '+-'[n < 0]

And finally, the plurals:

print(f"total: {n} item{'s'[n==1:]}")
answeredFeb 9, 2019 at 18:23
Walter Tross's user avatar

Comments

39

As already answered, yes, there is a ternary operator in Python:

<expression 1> if <condition> else <expression 2>

In many cases<expression 1> is also used as Boolean evaluated<condition>. Then you can useshort-circuit evaluation.

a = 0b = 1# Instead of this:x = a if a else b# Evaluates as 'a if bool(a) else b'# You could use short-circuit evaluation:x = a or b

One big pro of short-circuit evaluation is the possibility of chaining more than two expressions:

x = a or b or c or d or e

When working with functions it is more different in detail:

# Evaluating functions:def foo(x):    print('foo executed')    return xdef bar(y):    print('bar executed')    return ydef blubb(z):    print('blubb executed')    return z# Ternary Operator expression 1 equals to Falseprint(foo(0) if foo(0) else bar(1))''' foo and bar are executed oncefoo executedbar executed1'''# Ternary Operator expression 1 equals to Trueprint(foo(2) if foo(2) else bar(3))''' foo is executed twice!foo executedfoo executed2'''# Short-circuit evaluation second equals to Trueprint(foo(0) or bar(1) or blubb(2))''' blubb is not executedfoo executedbar executed1'''# Short-circuit evaluation third equals to Trueprint(foo(0) or bar(0) or blubb(2))'''foo executedbar executedblubb executed2'''# Short-circuit evaluation all equal to Falseprint(foo(0) or bar(0) or blubb(0))''' Result is 0 (from blubb(0)) because no value equals to Truefoo executedbar executedblubb executed0'''

PS: Of course, a short-circuit evaluation is not a ternary operator, but often the ternary is used in cases where the short circuit would be enough. It has a better readability and can be chained.

Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredOct 16, 2019 at 8:37
Frank's user avatar

Comments

36

Simulating the Python ternary operator.

For example

a, b, x, y = 1, 2, 'a greather than b', 'b greater than a'result = (lambda:y, lambda:x)[a > b]()

Output:

'b greater than a'
Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredNov 20, 2013 at 10:44
Sasikiran Vaddi's user avatar

4 Comments

Why not simplyresult = (y, x)[a < b] Why do you useslambda function?
@GrijeshChauhan Because on "compliated" expressions, e. g. involving a function call etc., this would be executed in both cases. This might not be wanted.
The use oflambda functions is an overkill for this question
@GrijeshChauhan In short, this implements the so-called “short-circuit evaluation”. Generally,P ? x : y orx if P else y can be written as(lambda:y, lambda:x)[P]() — but I doubt it has better performance and thus its necessity.
34
a if condition else b

Just memorize this pyramid if you have trouble remembering:

     condition  if           elsea                   b
answeredDec 6, 2018 at 14:45
shivtej's user avatar

Comments

34

Vinko Vrsalovic's answer is good enough. There is only one more thing:

Note that conditionals are anexpression, not astatement. This means you can't use assignment statements orpass or otherstatements within a conditionalexpression

Walrus operator in Python 3.8

After thewalrus operator was introduced in Python 3.8, something changed.

(a := 3) if True else (b := 5)

givesa = 3 andb is not defined,

(a := 3) if False else (b := 5)

givesa is not defined andb = 5, and

c = (a := 3) if False else (b := 5)

givesc = 5,a is not defined andb = 5.

Even if this may be ugly,assignments can be doneinside conditional expressions after Python 3.8. Anyway, it is still better to use normalifstatement instead in this case.

Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredDec 23, 2020 at 10:01
David Chung's user avatar

5 Comments

In the first example:(a := 3) if True else (b := 5) actually it's a redundant first walrus operator. This will do:a = 3 if True else (b := 5)
@AndrewAnderson No it's not redundant. You should compare both the first and the second examples. You can combine them and consider this:(a := 3) if x else (b := 5), you always get eithera orb assigned, not both. However, considera = 3 if x else (b := 5), whenx == False, you will geta = 5 andb = 5, where both them are assigned.
Yes, that's correct :). I considered this only forx=True case which is of course is limited.
Because we don't really write down this codeif True else, the reason of the first example is only compared with other examples.
In languages with proper ternaries plus unified assignment operators instead of needing an extra walrus one, the code to conditionally either assigna or assignb can be expressed : :::: :::: :::: :::: :::: :::x ? a = 3 : b = 5 - there's zero syntactical ambiguity despite total lack of parentheses, sinceb is alvalue, so: must act as a partition wall between them. How much cleaner is this compared to(a := 3) if x else (b := 5)
32

The ternary conditional operator simply allows testing a condition in a single line replacing the multiline if-else making the code compact.

Syntax:

[on_true] if [expression] else [on_false]

1- Simple Method to use ternary operator:

# Program to demonstrate conditional operatora, b = 10, 20# Copy value of a in min if a < b else copy bmin = a if a < b else bprint(min)  # Output: 10

2- Direct Method of using tuples, Dictionary, and lambda:

# Python program to demonstrate ternary operatora, b = 10, 20# Use tuple for selecting an itemprint( (b, a) [a < b] )# Use Dictionary for selecting an itemprint({True: a, False: b} [a < b])# lambda is more efficient than above two methods# because in lambda  we are assure that# only one expression will be evaluated unlike in# tuple and Dictionaryprint((lambda: b, lambda: a)[a < b]()) # in output you should see three 10

3- Ternary operator can be written as nested if-else:

# Python program to demonstrate nested ternary operatora, b = 10, 20print ("Both a and b are equal" if a == b else "a is greater than b"        if a > b else "b is greater than a")

Above approach can be written as:

# Python program to demonstrate nested ternary operatora, b = 10, 20if a != b:    if a > b:        print("a is greater than b")    else:        print("b is greater than a")else:    print("Both a and b are equal")# Output: b is greater than a
Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredApr 4, 2018 at 14:02
Ali Hallaji's user avatar

1 Comment

Note that the ternary operator is smaller (in memory) and faster than the nested if. Also, your nestedif-else isn't actually a rewrite of the ternary operator, and will produce different output for select values of a and b (specifically if one is a type which implements a weird__ne__ method).
31

You can do this:

[condition] and [expression_1] or [expression_2];

Example:

print(number%2 and "odd" or "even")

This would print "odd" if the number is odd or "even" if the number is even.


The result: If condition is true, exp_1 is executed, else exp_2 is executed.

Note: 0, None, False, emptylist, and emptyString evaluates as False.

And any data other than 0 evaluates to True.

Here's how it works:

If the condition [condition] becomes "True", then expression_1 will be evaluated, but not expression_2.

If we "and" something with 0 (zero), the result will always to be false. So in the below statement,

0 and exp

The expressionexp won't be evaluated at all since "and" with 0 will always evaluate to zero and there is no need to evaluate the expression. This is how the compiler itself works, in all languages.

In

1 or exp

the expressionexp won't be evaluated at all since "or" with 1 will always be 1. So it won't bother to evaluate the expression exp since the result will be 1 anyway (compiler optimization methods).

But in case of

True and exp1 or exp2

The second expression exp2 won't be evaluated sinceTrue and exp1 would be True when exp1 isn't false.

Similarly in

False and exp1 or exp2

The expressionexp1 won't be evaluated since False is equivalent to writing 0 and doing "and" with 0 would be 0 itself, but after exp1 since "or" is used, it will evaluate the expression exp2 after "or".


Note:- This kind of branching using "or" and "and" can only be used when the expression_1 doesn't have a Truth value of False (or 0 or None or emptylist [ ] or emptystring ' '.) since if expression_1 becomes False, then the expression_2 will be evaluated because of the presence "or" between exp_1 and exp_2.

In case you still want to make it work for all the cases regardless of what exp_1 and exp_2 truth values are, do this:

[condition] and ([expression_1] or 1) or [expression_2];
Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredAug 20, 2017 at 7:31
Natesh bhat's user avatar

1 Comment

If you want to use that in the context ofx = [condition] and ([expression_1] or 1) or [expression_2] andexpression_1 evaluates to false,x will be1, notexpression_1. Use the accepted answer.
29

More a tip than an answer (I don't need to repeat the obvious for the hundredth time), but I sometimes use it as a one-liner shortcut in such constructs:

if conditionX:    print('yes')else:    print('nah')

, becomes:

print('yes') if conditionX else print('nah')

Some (many :) may frown upon it as unpythonic (even, Ruby-ish :), but I personally find it more natural - i.e., how you'd express it normally, plus a bit more visually appealing in large blocks of code.

Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredMay 11, 2016 at 7:13
Todor Minakov's user avatar

4 Comments

I preferprint( 'yes' if conditionX else 'nah' ) over your answer. :-)
That is if you want toprint() in both cases - and it looks a bit more pythonic, I have to admit :) But what if the expressions/functions are not the same - likeprint('yes') if conditionX else True - to get theprint() only in truthyconditionX
To add to Frederick99's remark, another reason to avoidprint('yes') if conditionX else print('nah') is that it gives a SyntaxError in Python2.
The only reason it gives a syntax error is because in Python 2 print is a statement -print "yes", while in Python 3 it is a function -print("yes"). That can be resolved by either using it as a statement, or better -from future import print_function.
19

Many programming languages derived fromC usually have the following syntax of the ternary conditional operator:

<condition> ? <expression1> : <expression2>

At first, the Python'sbenevolent dictator for life (I meanGuido van Rossum, of course) rejected it (as non-Pythonic style), since it's quite hard to understand for people not used to C language. Also, the colon sign: already has many uses in Python. AfterPEP 308 was approved, Python finally received its own shortcut conditional expression (what we use now):

<expression1> if <condition> else <expression2>

So, firstly it evaluates the condition. If it returnsTrue,expression1 will be evaluated to give the result, otherwiseexpression2 will be evaluated. Due tolazy evaluation mechanics – only one expression will be executed.

Here are some examples (conditions will be evaluated from left to right):

pressure = 10print('High' if pressure < 20 else 'Critical')# Result is 'High'

Ternary operators can be chained in series:

pressure = 5print('Normal' if pressure < 10 else 'High' if pressure < 20 else 'Critical')# Result is 'Normal'

The following one is the same as previous one:

pressure = 5if pressure < 20:    if pressure < 10:        print('Normal')    else:        print('High')else:    print('Critical')# Result is 'Normal'
Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredDec 25, 2018 at 13:04
Andy Jazz's user avatar

Comments

16

Yes, Python have a ternary operator, here is the syntax and an example code to demonstrate the same :)

#[On true] if [expression] else[On false]# if the expression evaluates to true then it will pass On true otherwise On falsea = input("Enter the First Number ")b = input("Enter the Second Number ")print("A is Bigger") if a>b else print("B is Bigger")
Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredOct 21, 2018 at 20:14
realmanusharma's user avatar

4 Comments

I have added a one line statement example to check which number is big to elaborate it further
print is really not a good choice, as this will give a SyntaxError in Python2.
@Thierry Lathuille here I used print() function not print statement, print function is for Python 3 while print statement is for Python 2
The question has already been asked on SO, just try it with Python 2 and you will see by yourself. 'print('hello') is a perfectly valid syntax in Python 2.7, but the way it is parsed makes your code above throw a SyntaxError.
15

Python has a ternary form for assignments; however there may be even a shorter form that people should be aware of.

It's very common to need to assign to a variable one value or another depending on a condition.

>>> li1 = None>>> li2 = [1, 2, 3]>>>>>> if li1:...     a = li1... else:...     a = li2...>>> a[1, 2, 3]

^ This is the long form for doing such assignments.

Below is the ternary form. But this isn't the most succinct way - see the last example.

>>> a = li1 if li1 else li2>>>>>> a[1, 2, 3]>>>

With Python, you can simply useor for alternative assignments.

>>> a = li1 or li2>>>>>> a[1, 2, 3]>>>

The above works sinceli1 isNone and the interpreter treats that as False in logic expressions. The interpreter then moves on and evaluates the second expression, which is notNone and it's not an empty list - so it gets assigned toa.

This also works with empty lists. For instance, if you want to assigna whichever list has items.

>>> li1 = []>>> li2 = [1, 2, 3]>>>>>> a = li1 or li2>>>>>> a[1, 2, 3]>>>

Knowing this, you can simplify such assignments whenever you encounter them. This also works with strings and other iterables. You could assigna whichever string isn't empty.

>>> s1 = ''>>> s2 = 'hello world'>>>>>> a = s1 or s2>>>>>> a'hello world'>>>

I always liked the C ternary syntax, but Python takes it a step further!

I understand that some may say this isn't a good stylistic choice, because it relies on mechanics that aren't immediately apparent to all developers. I personally disagree with that viewpoint. Python is a syntax-rich language with lots of idiomatic tricks that aren't immediately apparent to the dabbler. But the more you learn and understand the mechanics of the underlying system, the more you appreciate it.

TylerH's user avatar
TylerH
21.3k84 gold badges84 silver badges121 bronze badges
answeredMar 11, 2020 at 6:49
Todd's user avatar

2 Comments

Very interesting! Two questions: 1) Clearly, if exactly one ofli1 andli2 is truthy, thenli1 or li2 will return its value. Ifbool(li1) returns the same value asbool(li2), willli1 or li2 consistently evaluate to be either one or the other (perhabs by position)? 2) how can you interpret what returns fromli1 and li2? I can't make sense of it with my test cases.
@TimH: 1) The right handor subexpressions of the assignment are interpreted left to right. If the first one is truthy, that's the one that gets assigned to the var. If it isn't truthy, the second one is assigned. 2) using theand operation wouldn't be like some sort ofternary operation as this answer discusses.
14

Other answers correctly talk about the Python ternary operator. I would like to complement by mentioning a scenario for which the ternary operator is often used, but for which there is a better idiom. This is the scenario of using a default value.

Suppose we want to useoption_value with a default value if it is not set:

run_algorithm(option_value if option_value is not None else 10)

or, ifoption_value is never set to a falsy value (0,"", etc.), simply

run_algorithm(option_value if option_value else 10)

However, in this case an ever better solution is simply to write

run_algorithm(option_value or 10)
Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredMay 19, 2020 at 16:47
user118967's user avatar

4 Comments

A valuable complement, but I disagree:option_value or 10 isnot better thanoption_value if option_value is not None else 10. It is shorter, indeed, but looks weird to me and may lead to bugs. What happens ifoption_value = 0, for instance? The first snippet will runrun_algorithm(0) becauseoption_value is notNone. The second and third snippets, however, will runrun_algorithm(10) because0 is a falsy. The two snippets are not equivalent, and hence one is not better than the other. And explicit is better than implicit.
@ruancomelli: Good point. I've modified the answer to reflect that correction.
As for it looking weird, I wonder if it looked weird to you because you noticed the imprecision (that it was not really equivalent). To me it sounds natural because it reminds me saying in English: "Use this or that (if the first option is unavailable)". But of course that is subjective. It is useful to know it does not look natural to everybody.
Much better! And thanks for the explanation regarding the "or"-idiom. It looks weird to me because I tend to think ofor as a function mapping two arguments to a boolean, so I expect it to return eitherTrue orFalse (this happens in many other programming languages). But "use this or that" is a nice mnemonic and will definitely help me (and hopefully others) to remember this pattern.
14

The syntax for the ternary operator in Python is:

[on_true] if [expression] else [on_false]

Using that syntax, here is how we would rewrite the code above using Python’s ternary operator:

game_type = 'home'shirt = 'white' if game_type == 'home' else 'green'

It's still pretty clear, but much shorter. Note that the expression could be any type of expression, including a function call, that returns a value that evaluates to True or False.

answeredApr 10, 2022 at 17:39
George Imerlishvili's user avatar

Comments

7

Pythonic way of doing the things:

"true" if var else "false"

But there always exists a different way of doing a ternary condition too:

"true" and var or "false"
Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredDec 29, 2021 at 18:53
Franz Gastring's user avatar

Comments

5

There are multiple ways. The simplest one is to use the condition inside the "print" method.

You can use

print("Twenty" if number == 20 else "Not twenty")

Which is equivalent to:

if number == 20:    print("Twenty")else:    print("Not twenty")

In this way, more than two statements are also possible to print. For example:

if number == 20:    print("Twenty")elif number < 20:    print("Lesser")elif 30 > number > 20:    print("Between")else:    print("Greater")

can be written as:

print("Twenty" if number == 20 else "Lesser" if number < 20 else "Between" if 30 > number > 20 else "Greater")
answeredFeb 6, 2022 at 13:46
Aldrin Saurov Sarker's user avatar

Comments

4

Yes, Python has a ternary operator, but it's different from C-syntax-like programming languages, where you'd do this:

condition ? value_if_true : value_if_false

Whereas Python follows this syntax:

value_if_true if condition else value_if_false

For example, in C++:

even_or_odd = x % 2 == 0 ? "even" : "odd";

Versus Python where you'd use:

even_or_odd = "even" if x % 2 == 0 else "odd"
Borisonekenobi's user avatar
Borisonekenobi
5294 silver badges19 bronze badges
answeredFeb 16, 2022 at 23:09
Heroes Of Balkan's user avatar

Comments

3

Theif else-if version can be written as:

sample_set="train" if "Train" in full_path else ("test" if "Test" in full_path else "validation")
Peter Mortensen's user avatar
Peter Mortensen
31.4k22 gold badges110 silver badges134 bronze badges
answeredFeb 1, 2022 at 13:23
DevLoverUmar's user avatar

Comments

3

Yes, Python has a ternary conditional operator, also known as the conditional expression or the ternary operator. The syntax of the ternary operator in Python is:

value_if_true if condition else value_if_false

Here's an example to illustrate its usage:

x = 5result = "Even" if (x % 2 == 0) else "Odd"print(result)

In this example, the condition x % 2 == 0 checks if x is divisible by 2. If the condition is True, the value "Even" is assigned to the variable result. Otherwise, the value "Odd" is assigned. The output will be:

Odd

It is a good idea to use parenthesis, in order to increase readability, when working with medium complexity operations:

"Even" if (x % 2 == 0) else "Odd"

Instead of:

"Even" if x % 2 == 0 else "Odd"

The ternary operator is a concise way to write simple conditional expressions in a single line. It can be particularly useful when assigning values or constructing expressions based on conditions. However, for more complex conditions or longer expressions, if possible it's generally better to use if-else statements for improved readability.

answeredJun 5, 2023 at 18:26
PhPires13's user avatar

1 Comment

This doesn't appear to add anything to the dozens of existing answers. Please make sure when answering posts (especially those with ~50+ answers) that your answer providesnew information!
3

For the Python 2.5 and above we can use the following[value] if [expression] else [elsevalue] to build a switch statement as follows:

     [value1] if [expression1] \else [value2] if [expression2] \else [value3] if [expression3] \else ... \else [elsevalue]

For example:

# input temperature in celciustemperature = 133# determine the water state based on the input temperaturewater_state =      "Ice"    if temp <   0 \              else "Liquid" if temp < 100 \              else "Steam"

For pre-Python 2.5 and as an interesting variation to James Brady's answerhttps://stackoverflow.com/a/394887/881441 one can extend this pattern to implement switch by chaining[expression] and [value] as follows:

   [expression1] and [value1] \or [expression2] and [value2] \or [expression3] and [value3] \or ... \or [elsevalue]

For example:

# input temperature in celciustemperature = 133# determine the water state based on the input temperaturewater_state = temperature <   0 and "Ice" \           or temperature < 100 and "Liquid" \           or "Steam"

As per James Brady's assessment and in this linkIs there an equivalent of C's "?:" ternary operator? this idiom is unsafe and can give the wrong results if any of the right-hand side values are falsy (are equivalent to a false boolean value).

answeredDec 10, 2024 at 9:50
Stephen Quan's user avatar

Comments

2

A neat way to chain multiple operators:

f = lambda x,y: 'greater' if x > y else 'less' if y > x else 'equal'array = [(0,0),(0,1),(1,0),(1,1)]for a in array:  x, y = a[0], a[1]  print(f(x,y))# Output is:#   equal,#   less,#   greater,#   equal
answeredMay 12, 2019 at 13:03
Yaakov Bressler's user avatar

Comments

Protected question. To answer this question, you need to have at least 10 reputation on this site (not counting theassociation bonus). The reputation requirement helps protect this question from spam and non-answer activity.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.