Python Ternary Operators and A Related Misconception

In Java and C, the expression <condition> ? <expression True> : expression False is widely used as an inline format. It could make the logic more clear than multi-line format for guys who understand this convention. Actually, there is a logically equivalent expression in Python, which is <expression True> if <condition> else <expression False>. However, I found a number of articles that have partial misconception, in which, they hold the argument that the expression <expression True> if <condition> else <expression False> is logically equivalent to the expression <condition> and <expression True> or <expression False>. The aim of this short post is to conduct a comparison between the two expressions and explain why the second expression is not logically equivalent to the first one.

Python logical expressions

This is the link to the Documentation of Boolean operations in Python3.

For convenience, I put the quotation here.

The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.

The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.

Experiments

In this case, it seems that the expression <condition> and <expression True> or <expression False> can be used as a ternary operator. However, there is still an exception. Let’s look at the code block.

1
2
3
4
5
6
>>> (2 > 1) and 0 or 1
1
>>> (2 > 1) and 2 or 1
2
>>> (2 > 1) and 3 or 2
3

Obviously, the expression (2 > 1) returns True, the first line should output 0 if this expression is logically equivalent to the expression <expression True> if <condition> else <expression False>. However, the output of the second line and the third line seem reasonable.

Explanation

In the first experiment (2 > 1) and 0 or 1, after calculating the value of (2 > 1), the Python interpreter evaluates the first operand of the and operator, which is True and then returns the resulting value, which is False. Since 0 and True returns False. After that, the interpreter evaluates the expression False or 1, which returns 1.

Conclusion

The logical expression <condition> and <expression True> or <expression False> could be used as a tricky way as a ternary operator. However, the edge case must be taken into consideration. The recommend way of handling this scenario is to use the expression <expression True> if <condition> else <expression False>, which is also officially recommended. However, the returning rules could also be used for other cases, for example or operator can be use to assign a default value, an example is as follows:

1
2
# when user.get_user_name() returns None, user_name will be assigned a default value.
user_name = user.get_user_name() or "Anonymous User"