简体   繁体   中英

Why does this “and-or” ternary expression syntax work?

I have recently been learning and working with Python, and came across the following code, which I was told is a common shorthand for a ternary expression in Python:

x = condition and expression1 or expression2

Now I'm familiar with the ? : ? : operators in C-like languages, and with Python's usual ternary expression x = expression1 if condition else expression2 , but this new expression seemed a bit odd to me.

Part of my confusion is that it doesn't seem very readable, ie when I read that line it doesn't immediately make it clear what is happening, but the other part is that I don't quite understand why it works.

In summary: Why does the expression above function the same as a C-like ternary expression?

The and operator evaluates its right operand ( expression1 ) if and only if the left operand is true. Likewise the or operator evaluates its right operand ( expression2 ) if and only if its left operand is false.

So if condition is true, expression1 gets evaluated. Assuming it evaluates to something truthy, the expression condition and expression1 is going to be true and expression2 will thus not be evaluated.

If condition is false, expression1 does not get evaluated and condition and expression1 is false. So expression2 will be evaluated.

The only problem would be if condition is true, but expression1 evaluates to something falsy. In that case both expression1 and expression2 would be evaluated. So this construct is broken when that's a possibility.

The real reason this works in Python is that these operators are short circuited and execution is left to right. If there is already enough information to answer the boolean expression the rest of the operands are not executed. This will not work as expected if expression1 returns false, it will execute both expressions.

The most common use of this is the statement with only one operator

condition and expression

That evaluates the expression if condition is true, the related statement using or executes the expression if condition is false.

This doesn't work in all languages, for example APL would evaluate all the operands.

and operator returns the left operand if it is falsy and the right operand if the left operand is truthy.

Conversly or operator returns the left operand if it is truthy and the right operand if the left one is falsy.

Example:

>>> [] and "test"  # [] is falsy
[]
>>> [] or "test"
"test"
>>> "foo" and "bar"  # "foo" is truthy
"bar"
>>> "foo" or "bar"
"foo"

As noted by other people these two constructs are not equivalent:

>>> True and 0 or 1
1
>>> 0 if True else 1
0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM