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
)
)
Answer from inspectorG4dget on Stack Overflow1 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
)
)
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 :P
Videos
Your first example (the horrid one-liner) is nested too. Horizontally nested. Your second example is vertically nested. They're both nested.
So which is better? The second one! Why? Because "sparse is better than dense" breaks the tie.
It's easy when you're Tim Peters - LOL ;-)
"Flat is better than nested" is about module organization and perhaps data structures, not your source code. The standard library, for example, mostly exists as top-level modules with very little nesting.
Don't nest the ternary operator, or even use it at all if you can avoid it. Complex is better than complicated. :)