Reputation: 991
I recently started using ternary operator but I encountered a case where I needed to use multiple ternary operator in the same line, but they didn't seem to work as I expected.
Can someone please give a explanation why those line give different result.
x = 1 if True else 2 + 3 if False else 4 # x = 1, I expected 5
x = (1 if True else 2) + (3 if False else 4) # x = 5
If I add parentheses I get the expected result, but I don't understand what the parentheses change.
And if I rotated the addition, without the parentheses, I get the correct value.
3 if False else 4 + 1 if True else 2 # x = 5
However, I get wrong result if the second ternary operator is False:
3 if False else 4 + 1 if False else 2 # x = 5 # x = 2 ???
Is it because you shouldn't multiple ternary operator in the same line, or is their an other reason?
Upvotes: 4
Views: 253
Reputation: 45741
Think of it as applying parentheses around each of the three inputs:
x = (1) if (True) else ((2 + 3) if (False) else (4))
Here you can clearly see that x
will equal 1
and that your 2 + 3...
won't be run.
When you 'rotated' it:
(3) if (False) else ((4 + 1) if (True) else (2))
So now the 3
doesn't run because the condition is False
so you get the 4 +...
term instead
and in your last case
(3) if (False) else ((4 + 1) if (False) else (2))
it returns 2
because the (4+1)
is the true condition for your second condition (which is False
)
If you're still confused, write it out as a regular if
statement:
x = (1) if (True) else ((2 + 3) if (False) else (4))
becomes
if True:
x = 1
else:
if False:
x = 2 + 3
else:
x = 4
Upvotes: 5
Reputation: 1352
The reason is operator precedence. Conditional expressions have the lowest-but-one precedence, only lambda expression is lower. Therefore, the expression
1 if True else 2 + 3 if False else 4
is evaluated as
1 if True else ((2 + 3) if False else 4)
which returns 1.
Upvotes: 6
Reputation: 31296
x = 1 if True else 2 + 3 if False else 4
is the same as
x = (1) if (True) else (2 + 3 if False else 4)
(Unless you want to play around with different constructs just for fun, I really don't recommend writing code like this.)
Upvotes: 4