代码之家  ›  专栏  ›  技术社区  ›  Chaitanya

python条件运算符是如何工作的?

  •  21
  • Chaitanya  · 技术社区  · 14 年前

    从我所读到的,我发现一个内置的三元运算符不存在(我很乐意知道更多关于它的信息)。

    我找到以下代码作为替代:

    def val():
        var = float(raw_input("Age:"))
        status = ("Working","Retired")[var>65]
        print "You should be:",status
    

    我不明白这段代码是如何工作的;有人能解释一下代码实际上是如何工作的吗?我还想知道三元运算符不存在的原因;关于这一点的任何引用或链接都将非常有用。

    我在WindowsVista上运行python 2.6.4。

    12 回复  |  直到 6 年前
        1
  •  51
  •   mipadi    12 年前

    python有一个构造,类似于c等中的三元运算符。它的工作原理如下:

    my_var = "Retired" if age > 65 else "Working"
    

    相当于C代码:

    my_var = age > 65 ? "Retired" : "Working";
    

    至于您发布的代码是如何工作的,让我们逐步了解它:

    ("Working","Retired")
    

    创建一个2元组(不可变列表),元素“working”位于索引0,而“retired”位于索引1。

    var>65
    

    如果var大于65,则返回true;否则返回false。当应用于索引时,它将转换为1(真)或0(假)。因此,这个布尔值为在同一行上创建的元组提供索引。

    为什么python不总是有三元运算符?简单的答案是,python的作者guido van rossum不喜欢/不喜欢它,显然他认为这是一个不必要的构造,可能会导致代码混淆(任何在C中看到大量嵌套三元运算符的人都可能会同意)。但是对于python 2.5,他让步了,并添加了上面看到的语法。

        2
  •  9
  •   TM. Randy Simon    14 年前

    python(2.5及更高版本)确实具有您要查找的内容的语法:

    x = foo if condition else bar
    

    如果 condition 是真的, x 将被设置为 foo ,否则将设置为 bar .

    实例:

    >>> age = 68
    >>> x = 'Retired' if age > 65 else 'Working'
    >>> x
    'Retired'
    >>> age = 35
    >>> y = 'Retired' if age > 65 else 'Working'
    >>> y
    'Working'
    
        3
  •  8
  •   mozillalives    14 年前

    因为真的强制转换为1,假的强制转换为0,所以如果var=70

    ("Working","Retired")[var>65]
    

    变成

    ("Working", "Retired")[1]
    

    一条很好的捷径…但我发现除了一个简单的条件外,它可能有点令人困惑,所以我同意TM的建议。

    "Retired" if var > 65 else "Working"
    
        4
  •  7
  •   tzot    6 年前

    索引到列表中

    使用

    [expression_when_false, expression_when_true][condition] # or
    (expression_when_false, expression_when_true)[condition]
    

    利用这样一个事实:在python中,true等于(但不是!)1和false等于(但不是!)0。上面的表达式构造两个元素的列表,并使用 条件 在列表中建立索引并只返回一个表达式。这种方法的缺点是对两个表达式都进行了计算。

    和或快捷方式

    自创建python以来,此操作有一种形式:

    condition and expression_when_true or expression_when_false
    

    这采用了一个快捷方式,只计算一个表达式,但有一个容易出错的缺点: 表达式“当”为“真时” 不能 计算为非真值,否则结果为 表达式“假时” . and or 在python中是否为“短路”,并应用以下规则:

    a and b #→ a if a is false, else b
    a or b  #→ a if a is true, else b
    

    如果 条件 是假的,那么 表达式“当”为“真时” 从未进行过评估,结果是 表达式“假时” . otoh,如果 条件 是真的,那么结果就是( 表达式“当”为“真时” 表达式“假时” );参考上表。

    三元条件运算符

    当然,由于python 2.5,有一个三元条件运算符:

    expression_when_true if condition else expression_when_false
    

    操作数的奇怪顺序(如果您习惯于类C三元条件运算符)是可归因的。 to many things 总的意图是 条件 大多数情况下都应该是正确的,这样最常见的输出就出现在第一位,并且是最可见的。

        5
  •  2
  •   Arseny    11 年前

    短路布尔表达式

    还可以选择短路逻辑操作:

    >>> (2+2 == 4) and "Yes" or "No"
    'Yes'
    >>> (2+2 == 5) and "Yes" or "No"
    'No'
    

    在您的示例中:

    >>> (int(raw_input("Age: ")) > 65) and "Retired" or "Working"
    Age: 20
    'Working'
    >>> (int(raw_input("Age: ")) > 65) and "Retired" or "Working"
    Age: 70
    'Retired'
    

    在中阅读有关此技术的更多信息 Charming Python: Functional Programming in Python, Part 1 .

        6
  •  0
  •   SilentGhost    14 年前

    在您发布的代码中,下面一行是模仿三元的:

    status = ("Working","Retired")[var>65]
    

    这里元组 ("Working","Retired") 使用索引访问 [var>65] 其计算结果为 True ( 1 False ( 0 )当它被索引访问时 , status 'Working' 如果索引是 1个 然后它将被“退休”。这是一种相当模糊的条件赋值方法,使用PY2.5中引入的普通三元语法,如前所述。

        7
  •  0
  •   Tordek    14 年前

    最初没有三元运算符,因为“显式比隐式好”,它被认为是非对称的。我也不太喜欢Python的三元运算,但它确实存在:

    x = foo if condition else bar
    

    如TM所示。

    至于 status = ("Working","Retired")[var>65] , var > 65 返回布尔值:true或false;但是,python对布尔类型的处理非常弱: True 1 False 0 在某些情况下。你可以通过 >>> True == 1 .

        8
  •  0
  •   Paul Stephenson    14 年前
    status = ("Working","Retired")[var>65]
    

    此行用作三元运算符,因为表达式 var>65 返回1或0,具体取决于 var 是否大于65。所以如果 变量65 ,则该行变为:

    status = ("Working","Retired")[1]
    

    也就是说,序列的第二个元素 ("Working","Retired") . 它看起来很奇怪,但如果你改成这样写的话就不是了:

    status_sequence = ("Working","Retired")
    status = status_sequence[1]
    

    所以 status = "Retired" .

    同样,如果 var<=65 然后它变成

    status = ("Working","Retired")[0]
    

    status = "Working" .

        9
  •  0
  •   Peter Hansen    14 年前

    只有该代码的“status=”行实现类似三元运算符的操作。

    status = ("Working","Retired")[var>65]
    

    这将创建一个两元素元组,其中字符串“working”位于索引0,而“retired”位于索引1。然后,它索引到该元组中,使用表达式的结果选择这两个项中的一个。 var > 65 .

    如果var的值大于65,则此表达式将返回true(相当于1,因此选择“retired”)。否则将返回false(相当于0,因此选择“working”)。

    然而,这种方法与三元运算符有一个关键区别,尽管在您的特定示例中并不重要。使用元组索引方法,将计算两个值,但只返回一个值。对于三元运算符,实际上只评估两个值中的一个;这被称为“短路”行为。在这种情况下很重要:

    status = funcA() if var > 65 else funcB()
    status = (funcB(), funcA())[var > 65]
    

    在第一种情况下,调用funca()。 调用了funcb(),但不能同时调用两者。在后一种情况下,首先调用这两个函数,结果存储在元组中——然后只挑选一个函数并丢弃该元组。

    这对于理解funca()或funcb()是否具有“副作用”尤其重要,这意味着它们在执行时会更改其他数据。

        10
  •  0
  •   Tim Pietzcker    14 年前

    在python 2.6及更高版本中:

    print "You should be {0}.".format("retired" if var>65 else "working")
    

    在python 3.1及更高版本中:

    print ("You should be {}.".format("retired" if var>65 else "working"))
    
        11
  •  0
  •   tzot    14 年前

    这是带有python三元运算符的窗体

    def val():
        var = float(raw_input("Age:"))
        status = "Retired" if var > 65 else "Working"
        print "You should be:",status
    

    您所展示的代码有点复杂:它创建了一个元素位于0和1位置的两元素元组。要选择正确的元素,它使用返回布尔值的条件,但python中的布尔值是整数,因此可以将其用作 特殊的 索引(可以是0或1)。

        12
  •  0
  •   João Portela    14 年前

    试着根据这里给出的答案给出一个完整的答案。

    您找到的方法(请不要使用此方法,因为它不太可读):

    def val():
        var = float(raw_input("Age:"))
        status = ("Working","Retired")[var>65]
        print "You should be:",status
    

    使用python 2.5+语法:

    def val():
        var = float(raw_input("Age:"))
        status = "Working" if var>65 else "Retired"
        print "You should be:",status
    

    使用一些人仍然喜欢的其他常用方法:

    def val():
        var = float(raw_input("Age:"))
        status = var>65 and "Working" or "Retired"
        print "You should be:",status
    

    我个人倾向于使用最后一个,因为操作数的顺序与C三元运算符相同。

    编辑: 发现了最后一种方法(THX罗伯托·邦瓦莱)的一些问题。
    维基百科:

    如果op1可以 “错误”值(无、假、0、和 空序列或集合,_ 表达式将返回op2 (不管是真的还是假的) 而不是(falsy)op1

    所以我最后的建议是 使用2.5+三元运算符 因为它很简单,可读性好,并且提供了短路行为。