标签云

微信群

扫码加入我们

WeChat QR Code

If Python does not have a ternary conditional operator, is it possible to simulate one using other language constructs?


Though Pythons older than 2.5 are slowly drifting to history, here is a list of old pre-2.5 ternary operator tricks: "Python Idioms", search for the text 'Conditional expression' . Wikipedia is also quite helpful Ж:-)

2019年05月24日53分12秒

In the Python 3.0 official documentation referenced in a comment above, this is referred to as "conditional_expressions" and is very cryptically defined.That documentation doesn't even include the term "ternary", so you would be hard-pressed to find it via Google unless you knew exactly what to look for.The version 2 documentation is somewhat more helpful and includes a link to "PEP 308", which includes a lot of interesting historical context related to this question.

2019年05月24日53分12秒

"ternary" (having three inputs) is a consequential property of this impelmentation, not a defining property of the concept. eg:SQL has case [...] { when ... then ...} [ else ... ] end for a similar effect but not at all ternary.

2019年05月24日53分12秒

also ISO/IEC 9899 (the C programming language standard) section 6.5.15 calls it the "the condtitional operator"

2019年05月24日53分12秒

Wikipedia covers this thoroughly in the article "?:".

2019年05月23日53分12秒

The order may seems strange for coders however f(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...

2019年05月23日53分12秒

Be careful with order of operations when using this. For example, the line z = 3 + x if x < y else y. If x=2 and y=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.

2019年05月24日53分12秒

The point was if you want to perform additional evaluations after 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) or z = (x if x < y else y) + 3)

2019年05月23日53分12秒

what if there are multiple conditions ?

2019年05月24日53分12秒

MrGeek, I see what you mean, so you would basically be nesting the operations: ` "foo" if Bool else ("bar" if Bool else "foobar") `

2019年05月24日53分12秒

Note that this one always evaluates everything, whereas the if/else construct only evaluates the winning expression.

2019年05月24日53分12秒

(lambda: print("a"), lambda: print("b"))[test==true]()

2019年05月23日53分12秒

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>)]. The bool() function has been around since v2.2.1.

2019年05月24日53分12秒

This is great for code-golf, not so much for actual code. Although I have gotten so used to it that I do use it sometimes for conciseness when doing something obvious like picking between two string constants.

2019年05月24日53分12秒

I've done a similar trick -- only once or twice, but done it -- by indexing into a dictionary with True and False 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.

1970年01月01日00分03秒

The remedy is to use (test and [true_value] or [false_value])[0], which avoids this trap.

2019年05月23日53分12秒

Ternary operator usually executes faster(sometimes by 10-25%).

2019年05月24日53分12秒

volcano Do you have source for me?

2019年05月24日53分12秒

OrangeTux Here's the disassembled code. Using the method ThomasH suggested would be even slower.

2019年05月24日53分12秒

What's the difference between this and the top answer?

2019年05月24日53分12秒

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.

2019年05月24日53分12秒

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.

2019年05月23日53分12秒

Somehow, I'm able to understand this better than the top answer.

2019年05月24日53分12秒

result = {1: x, 0: y}[a > b] is another possible variant (True and False are actually integers with values 1 and 0)

2019年05月24日53分12秒

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 of if else if.

2019年05月23日53分12秒

The behaviour is not identical - q("blob", on_true, on_false) returns on_false, whereas on_true if cond else on_false returns on_true. A workaround is to replace cond with cond is not None in these cases, although that is not a perfect solution.

2019年05月23日53分12秒

Why not bool(cond) instead of cond is True?The former checks the truthiness of cond, the latter checks for pointer-equality with the True object.As highlighted by AndrewCecil, "blob" is truthy but it is not True.

2019年05月23日53分12秒

Wow, that looks really hacky! :) Technically, you can even write [on_false, on_True][cond is True] so the expression becomes shorter.

2019年05月23日53分12秒

There is no short circuit in this answer.If on_true and on_false are expensive to call this is a bad answer.

2019年05月24日53分12秒

This blogger found python's ternary operator to be unnecessarily different than most other languages.

2019年05月24日53分12秒

Ruby works also with a = true ? 1 : 0

2019年05月24日53分12秒

"Now you can see the beauty of python language. its highly readable and maintainable." I don't see the relevance of this sentence, nor how the ternary operator syntax demonstrates it.

2019年05月24日53分12秒

It may sound opinionated; but what it essentially says is that it the Python syntax is likely to be understood by a person who never saw a ternary operator, while very few people will understand the more usual syntax unless they have been told first what it means.

2019年05月23日53分12秒

Algol68:a=.if. .true. .then. 1 .else. 0 .fi. This may be expressed also a=(.true.|1|0)As usual Algol68 is an improvement over its successors.

2019年05月24日53分12秒

expression1 or expression2 being similar and with the same drawbacks/positives as expression1 || expression2 in javascript

2019年05月24日53分12秒

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!!

2019年05月24日53分12秒

AaronHall Although your use of metasyntactic expressionN 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?

2019年05月24日53分12秒

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!)

2019年05月24日53分12秒

Why not simply result = (y, x)[a < b] Why do you uses lambda function ?

2019年05月23日53分12秒

GrijeshChauhan Because on "compliated" expressions, e. g. involving a function call etc., this would be executed in both cases. This might not be wanted.

2019年05月23日53分12秒

If you want to use that in the context of x = [condition] and ([expression_1] or 1) or [expression_2] and expression_1 evaluates to false, x will be 1, not expression_1. Use the accepted answer.

2019年05月24日53分12秒

Note that the ternary operator is smaller (in memory) and faster than the nested if.Also, your nested if-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).

2019年05月24日53分12秒

I prefer print( 'yes' if conditionX else 'nah' ) over your answer. :-)

2019年05月24日53分12秒

That is if you want to print() in both cases - and it looks a bit more pythonic, I have to admit :) But what if the expressions/functions are not the same - like print('yes') if conditionX else True - to get the print() only in truthy conditionX

2019年05月24日53分12秒

To add to Frederick99's remark, another reason to avoid print('yes') if conditionX else print('nah') is that it gives a SyntaxError in Python2.

2019年05月24日53分12秒

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.

2019年05月23日53分12秒

I have added a one line statement example to check which number is big to elaborate it further

2019年05月24日53分12秒

print is really not a good choice, as this will give a SyntaxError in Python2.

2019年05月24日53分12秒

Thierry Lathuille here I used print() function not print statement, print function is for Python 3 while print statement is for Python 2

2019年05月24日53分12秒

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.

2019年05月23日53分12秒

What is the correct one please tell

2019年05月24日53分12秒

While useful for similar problems, this is not a ternary conditional.It works to replace x if x else y, but not x if z else y.

2019年05月23日53分12秒