【问题标题】:What's the evaluation order of conditional expression in Python?Python中条件表达式的求值顺序是什么?
【发布时间】:2012-03-22 09:05:03
【问题描述】:

我知道 Python 中的条件表达式是 X if C else Y,但是我在使用它时遇到了一些问题。

我有两个代码要比较。

代码 1:

def fun(p):
    if len(p) >= 2:
        p[1] = 'Ok'
    else:
        p.append('Ok')
p = [1]
fun(p)
print p

代码 1 的输出:

[1, 'Ok']

代码 2:

def fun(p):
    (p[1] = 'Ok') if (len(p) >= 2) else p.append('OK')

p = [1]
fun(p)
print p

代码2的输出:

    (p[1] = 'Ok') if (len(p) >= 2) else p.append('OK')
      ^
SyntaxError: invalid syntax

我知道代码1,其格式为“if C : X else: Y”,求值顺序为:

  1. C
  2. X

代码 2 抛出语法错误,原因可能是 p[1] 不存在。所以我猜格式“X if C else Y”的评估如下:

  1. X
  2. C

但这只是我的猜测。有谁知道代码 2 错误而代码 1 正确的真正原因?

【问题讨论】:

  • 请注意,赋值是语句,不能出现在表达式上下文中。这就是代码 2 中错误的原因。

标签: python conditional-operator


【解决方案1】:

你有一个SyntaxError 的原因是因为 Python 区分 statementsexpressions

作业,例如

p[1] = 'Ok'

语句,不能成为表达式的一部分,包括条件表达式。请参阅What is the difference between an expression and a statement in Python? 了解更多信息。

不考虑评估顺序 -- SyntaxErrors 发生在 任何 代码被评估之前,当它被解析时。

if 语句和条件表达式中,求值顺序是ether

  1. 条件
  2. 真实陈述

  1. 条件
  2. 虚假陈述

所以,在

if condition:
    true_statement
else:
    false_statement

true_statement if condition else false_statement

根据条件的真实性,仅评估真正的 fase 语句。

【讨论】:

  • 感谢您的帮助,我现在知道其中的区别了。
【解决方案2】:

正如 Dan D. 所指出的,您不能在表达式上下文中使用语句。

为了学习——我不建议这样做——我将向你展示如何使用内联 X if C else Y 来完成你想要做的事情:

def fun(p):
    p.__setitem__(1, 'Ok') if len(p) >= 2 else p.append('OK')

如您所见,您的第一个版本更具可读性。

【讨论】:

  • 可读性是您不这样做的唯一原因吗? (使用三元运算符语法来产生副作用似乎是不礼貌的。)
  • @Li-aung 当然你是对的——这是在滥用三元运算符,因为我们只是丢弃了答案(NoneNone)。但至少我们对此很明确——毫无疑问,这样做是为了产生副作用。
  • @lazyr 感谢您给我另一个解决方案。
【解决方案3】:

赋值不是表达式(其他人指出了这一点)。因此语法错误。

关于您关于评估顺序的问题:

if-else 表达式(!)中,首先计算条件操作数,然后计算 then 操作数(最左边)或 else 操作数(最右边)。另一个操作数被评估。

or 表达式中,操作数从最左到右 (a or b or c or d or ...) 进行求值,但直到找到布尔值为 True 的操作数。剩余的表达式求值。

and 表达式中,操作数从最左到右 (a and b and c and d and ...) 进行计算,但直到找到布尔值为 False 的操作数。剩余的表达式求值。

在外部表达式之前计算内部表达式(当然):third(second(first()))

所有其他情况a() + b()f(g(), h())a[b[c]] = d() + e)中,订单定义为specified。通常它是从左到右的,除了赋值(它在左边之前)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    • 2021-04-24
    • 1970-01-01
    相关资源
    最近更新 更多