2012-03-22 80 views
1

我知道Python中的条件表达式是X,如果C else Y,但我在使用它时遇到了一些问题。Python中条件表达式的评估顺序是什么?

我有两个代码进行比较。

代码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,其格式为: “如果C:X其它:Y”,评价的顺序是:

  1. Ç
  2. X
  3. ÿ

代码2抛出一个语法错误,其原因可以是p [1]不存在。所以我想,格式为 “X如果C别的Y” 被评价为如下:

  1. X
  2. Ç
  3. Ÿ

不过,这只是我的猜测。有没有人知道代码2错误而代码1正确的真正原因?

+2

请注意,赋值是语句,不能出现在表达式上下文中。这是代码2中出现错误的原因。 – 2012-03-22 09:07:09

回答

4

你有SyntaxError的原因是因为Python 声明表达区分。

分配,像

p[1] = 'Ok' 

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

评估顺序没有进入 - SyntaxError s发生在之前任何代码被评估,当它被解析时。

在这两种if语句和条件表达式,评估的顺序是

  1. 条件
  2. 如实陈述

  1. 条件
  2. 虚假陈述

所以,在

if condition: 
    true_statement 
else: 
    false_statement 

true_statement if condition else false_statement 

只有真正的FASE声明进行评估,根据条件的感实性。

+0

感谢您的帮助,我现在知道这些差异。 – Huo 2012-03-22 09:27:24

0

正如Dan D.指出的那样,表达式上下文中不能有语句。

在学习的兴趣 - 我不建议做这种方式 - 我会告诉你如何,你可以使用内联X if C else Y来完成你正在试图做的:

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

正如你所看到的,你的拳头版本更具可读性。

+0

可读性是你不这样做的唯一原因吗? (对于副作用,使用三元运算符语法似乎是不礼貌的。) – 2012-03-22 09:20:12

+0

@ Li-aung当然你是对的 - 这是滥用三元运算符,因为我们只是抛弃了答案(即None '或'None')。但至少我们明确表示 - 毫无疑问,这是明确的副作用。 – 2012-03-22 09:23:51

+0

@lazyr谢谢你给我另一个解决方案。 – Huo 2012-03-22 09:29:27

0

要解决你的语法错误,你可以使用:

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

顺便说一句,这里的条件不同时评估(左边成等价的表达改变语句)无论条件属于哪种情况。您可以轻松地证实这一点:

>>> def foo(x): 
... print x 
... 
>>> foo('spam') if True else foo('eggs') 
spam 
>>> foo('spam') if False else foo('eggs') 
eggs 
>>> 1/0 if False else foo('hello') 
hello 

请注意,只有一个函数调用打印,所以只有一边进行评估。

+0

谢谢你的帮助。 – Huo 2012-03-22 09:31:22

0

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

关于你提到的有关评估顺序问题:(!)

的if-else表达式第一条件操作数进行评估,那么无论是当时的操作数(最左边)或其他操作数(最右边)被评估。另一个操作数是而不是评估。

表达式中,操作数从最左边到最右边(a or b or c or d or ...)进行求值,但直到找到其布尔值为True的值为止。剩下的表达式是而不是评估。

表达式中,操作数从最左边到最右边(a and b and c and d and ...)进行求值,但是直到找到布尔值为False的一个为止。剩下的表达式是而不是评估。外表达式(当然)之前

内表达式进行求值:third(second(first()))

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