简体   繁体   中英

implementing ternary operator in python using and/or combinations

I am learning python using the excellent book by Mark Lutz. I come across this statement that the ternary operator in python, which is effectively this:

if a: 
   b
else: 
   c

can be written in 2 ways:

  1. b if a else c : using normal ternary syntax of python and

  2. ((a and b) or c) : using the equivalent but trickier and/or combination

I find the second representation disconcerting as it doesn't go well with my instinct. I tried these 2 syntax on the interactive prompt and found different answers for special case of b = 0. (assume b = 0, a = 4, c = 20)

  1. 0 if 4 else 20 outputs 0
  2. ((4 and 0) or 20) outputs 20

It appears that the 2 expressions are equivalents for all the truthy values of b but are not equivalent for all the falsy values of b .

I want to know, is there anything that I am missing here. Is my analysis wrong? Why does it say so in the book that the two cases are equivalent. Please enlighten my coarse mind. I am new to python. Thanks in advance.

You are right, the second approach is great in most cases.

From the python docs:

Before this syntax was introduced in Python 2.5, a common idiom was to use logical operators: [expression] and [on_true] or [on_false]

Right after that they mention:

"However, this idiom is unsafe, as it can give wrong results when on_true has a false boolean value. Therefore, it is always better to use the ... if ... else ... form.

Here's a reference: https://docs.python.org/3.3/faq/programming.html#is-there-an-equivalent-of-cs-ternary-operator

Adding brief sample per request:

a = True
b = False
c = True

# prints False (for b) correctly since a is True
if a:
   print b
else: 
   print c

# prints False (for b) correctly since a is True
print b if a else c 

# prints True (for c) incorrectly since a is True and b should have been printed
print ((a and b) or c) 

The perspective of the author here is different which should be considered. Let me try to explain with the code & inline comments:

#This if condition will get executed always(because its TRUE always for any number) except when it is '0' which is equivalent to boolean FALSE.
#'a' is the input which the author intends to show here. 'b' is the expected output
if a: 
   print(b)
else: 
   print(c)

#equivalent
print(b) if a else print(c) 
print((a and b) or c)

You are supposed to change the input and check the output. Whereas, you change the OUTPUT directly and try to check the output, which is not working. So, you are testing the wrong way is my opinion. The input here is a. Output here is b. Case 1: b = 12 a = 1 c = 20

*Case 2:
b = 12
a = 0
c = 20*
*Dont change 'b'. Change only 'a' and test is the conceptual idea. Coz, 'b' is the output.*

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