Python多个嵌套三元表达式

时间:2017-06-19 17:24:57

标签: python for-loop nested ternary-operator

使用Python(2.7)三元表达式x if cond else y在按顺序评估这些嵌套的多个表达式时,逻辑顺序是什么:例如

1 if A else 2 if B else 3

为此绘制真值表会显示为1 if A else (2 if B else 3)而不是(1 if A else 2) if B else 3

A      True  False
B                 
True      1      2
False     1      3

有人可以解释为什么这个按此顺序执行,并且可能会建议一些材料,直截了当地说明为什么使用/首选?

在使用内联for语句考虑排序时,这似乎并不明显:

>>>[(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)]

4 个答案:

答案 0 :(得分:3)

1 if A else 2 if B else 3转换为:

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

您的三元表达式可以用括号解释如下:

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

答案 1 :(得分:2)

  

有人可以解释为什么要按此顺序执行,并可能建议一些可以直观地理解为什么使用/优先使用此内容的材料吗?

我正在尝试通过解决一个简单但更笼统的问题来回答您问题的“直觉”部分。

'''
+-----------------------------------------------------------------------------------+
|                                    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(CF)else (E22) )


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

以下是f_nested_if_else()f_nested_ternary()为何相等的可视化视图。

#     +-----------------------------------------------------------------------------+
#     |                               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) ) 
------------------------------------------------------------------------------------+

希望这种可视化可以使您直观地了解嵌套三元表达式的计算方式:P

答案 2 :(得分:1)

两种用途都是它们相似的结构的一线同源。 inspectorG4dget已经为您制定了if版本。 for子句按给定顺序嵌套:

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

if部分与解析器视图的工作方式相同:当它点击1 if A时,解析器将if A作为顶级决策。正如语法中所定义的那样,这个嵌套是从右到左绑定的:if B是最里面的(内部更多?)。

答案 3 :(得分:0)

布尔谓词在许多语言中被定义为尽可能快地终止,最终结果是已知的,特别是如果左侧是左侧,则根本不会对or-expression的右侧进行评估。真正。它实际上与列表理解中发生的解构赋值无关。