Python multiple nested ternary expression

Question:

With the Python (2.7) ternary expression x if cond else y what is the logical order when evaluating multiple expressions of these nested in order: e.g.

1 if A else 2 if B else 3

Drawing out the truth table for this is appears this is evaluated as 1 if A else (2 if B else 3) rather than (1 if A else 2) if B else 3:

A      True  False
B
True      1      2
False     1      3

Could someone please explain why this is executed in this order, and possibly suggest some material that gives an intuition about why this is used/preferred?

This doesn’t seem obvious when considering the ordering using the inline for statement:

>>>[(i, j, k) for i in range(1) for j in range(2) for k in range(3)]
[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 1, 0), (0, 1, 1), (0, 1, 2)]

1 if A else 2 if B else 3 translates to this:

def myexpr(A, B):
if A:
return 1
else:
if B:
return 2
else:
return 3

Your ternary expression can be interpreted with parentheses as follows:

(
(1 if A) else (
(2 if B) else 3
)
)

Boolean predicates are in many languages defined to terminate as quickly as possible, as quickly as the end result is known, and especially that the right hand side of an or-expression does not get evaluated at all if the left hand side is true. It really has nothing to do with the destructuring assignment that happens in the list comprehension.

Both uses are one-line cognates of the structures they resemble. inspectorG4dget already laid out the if version for you.
The for clauses nest in the given order:

for i in range(1):
for j in range(2):
for k in range(3):
result.append( (i, j, k) )

The if portion works the same way from the parser’s view: when it hits 1 if A, the parser takes if A as the top-level decision. As defined in the grammar, this nesting is bound from right to left: if B is the innermost (inner-more?).

Could someone please explain why this is executed in this order, and possibly suggest some material that gives an intuition about why this is used/preferred?

I’m trying to answer the "intuition" part of your question by solving a simple but more general problem.

'''
+-----------------------------------------------------------------------------------+
|                                    Problem:                                       |
+-----------------------------------------------------------------------------------+
| Convert a                                                                         |
| nested if-else block into                                                         |
| a single line of code by using Pythons ternary expression.                        |
| In simple terms convert:                                                          |
|                                                                                   |
|      1.f_nested_if_else(*args) (  which uses                                      |
|      ````````````````````        nested if-else's)                                |
|            |                                                                      |
|            +--->to its equivalent---+                                             |
|                                     |                                             |
|                                     V                                             |
|                              2.f_nested_ternary(*args) (     which uses           |
|                              ```````````````````       nested ternary expression) |
+-----------------------------------------------------------------------------------+
'''
'''
Note:
C:Conditions  (C, C1, C2)
E:Expressions (E11, E12, E21, E22)
Let all Conditions, Expressions be some mathematical function of args passed to the function
'''

#-----------------------------------------------------------------------------------+
#| 1. |      Using nested if-else                                                   |
#-----------------------------------------------------------------------------------+
def f_nested_if_else(*args):
if(C):
if(C1):
return E11
else:
return E12
else:
if(C2):
return E21
else:
return E22

#-----------------------------------------------------------------------------------+
#| 2. |      Using nested ternary expression                                        |
#-----------------------------------------------------------------------------------+
def f_nested_ternary(*args):
return ( (E11) if(C1)else (E12) )   if(C)else   ( (E21) if(C2)else (E22) )

#-----------------------------------------------------------------------------------+
#-----------------------------------------------------------------------------------|
#-----------------------------------------------------------------------------------|
#-----------------------------------------------------------------------------------|
#-----------------------------------------------------------------------------------+

Here is a visualization of why f_nested_if_else() and f_nested_ternary() are equivalent.

#     +-----------------------------------------------------------------------------+
#     |                               Visualization:                                |
#     +-----------------------------------------------------------------------------+
#     |         Visualize the ternary expression like a binary tree :               |
#     |           -Starting from the root and  moving down to the leaves.           |
#     |           -All the internal nodes being conditions.                         |
#     |           -All the leaves being expressions.                                |
#     +-----------------------------------------------------------------------------+
_________________
|f_nested_ternary|
``````````````````
( (E11) if(C1)else (E12) )   if(C)else   ( (E21) if(C2)else (E22) )
|       |        |          |            |       |        |
|       |        |          |            |       |        |
V       V        V          V            V       V        V
Level-1|                  +----------------(C)-----------------+
--------             True/          __________________           False
V           |f_nested_if_else|            V
Level-2|          +----(C1)----+    ``````````````````     +----(C2)----+
--------     True/              False                True/              False
V                V                       V                V
Level-3|    ( (E11)            (E12) )               ( (E21)            (E22) )
------------------------------------------------------------------------------------+

Hope this visualization gave you an intuition of how nested ternary expressions are evaluated ðŸ˜›

Can anybody find whats wrong with this code? It gives me syntax error in hackerranks challenges

If __name__ == â€˜__main__â€™:
n = int(input().strip())
print(â€˜Wierdâ€™) if n%2 == 0 else print(â€˜Not Weirdâ€™) if (n%2==0 and 2<=n<=5) else print(â€˜Weirdâ€™) if (n%2==0 and 6<=n<=20) else print(â€˜Not Weirdâ€™) if 20<=n
Categories: questions
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.