在Python中,逻辑运算符(操作顺序)的优先级(先后顺序)为NOT、AND、OR。

122
据我所知,在C&C++中,NOT AND&OR的优先级顺序是NOT>AND>OR。但在Python中,似乎并不以类似的方式工作。我尝试在Python文档中搜索,但没有找到(我猜我有点不耐烦)。有人能为我解答一下吗?

3
你能举一个运算符优先级不像你想象的那样工作的例子吗? - dodgethesteamroller
不是大于和大于等于 - user8866053
8个回答

147

根据运算符优先级的文档,从高到低的顺序是:NOTANDOR

以下是完整的优先级表,从最低优先级到最高优先级。每行具有相同的优先级,并且从左到右分组。

 0. :=
 1. lambda
 2. ifelse
 3. or
 4. and
 5. not x
 6. in, not in, is, is not, <, <=, >, >=, !=, ==
 7. |
 8. ^
 9. &
10. <<, >>
11. +, -
12. *, @, /, //, %
13. +x, -x, ~x
14. **
14. await x
15. x[index], x[index:index], x(arguments...), x.attribute
16. (expressions...), [expressions...], {key: value...}, {expressions...}

2
请注意,当涉及到优先级高于算术运算符时,**有一些脚注中的例外情况。 - Martijn Pieters
1
这让我这个数学家感到困惑:在算术中,我们会说它比算术运算符具有优先级。在其右侧,“”运算符不具有算术运算的优先级,但在其左侧却具有...例如,“5*22 == 5*(22)”。然而,正确的说法是“2-1 == 2**(-1)”。 - PhilMacKay
1
@PhilMacKay - 看起来,例如减号是int字面量的一部分,但是在使用ast解析时并非如此 - 它是具有USub和操作数1UnaryOp。真正的原因是没有其他解析方式。即2 **不是二元减法的正确左操作数。因此出现了“指数优先级异常”,但“仅限于右侧”。 - Tomasz Gandor

42

您可以执行以下测试,以确定andor的优先级。

首先,在Python控制台中尝试0 and 0 or 1

如果or首先绑定,那么我们期望输出0

在我的控制台中,输出为1。这意味着and要么首先绑定,要么与or相等(也许表达式从左到右求值)。

然后尝试1 or 0 and 0

如果orand与内置的从左到右评估顺序一样绑定,那么我们应该得到0作为输出。

在我的控制台中,输出为1。然后我们可以得出结论,and的优先级高于or


8
更明确地说,这些表达式的求值结果分别为:((0 and 0) or 1)(1 or (0 and 0)) - Conchylicultor
2
然而,在第二个表达式中,(0 and 0) 永远不会被计算,因为如果 exp1True,则 (exp1 or exp2) 直接返回。 同样,在第一个表达式中,and 0 部分永远不会被计算,因为如果 exp1False,则 exp1 and exp2 直接返回。 - Conchylicultor

22

6

布尔运算的优先级由弱到强如下所示:

  1. or
  2. and
  3. not x
  4. is not; not in

如果运算符具有相等的优先级,则从左到右进行评估。


抱歉,你的第2点技术上是正确的,但仍然非常具有误导性。首先,文档似乎没有改变。其次,你的意见#2(建议从左到右评估“and”和“not x”)在技术上等同于官方效果,但这只是因为当在“cond1 and not cont2”中时,默认情况下Python必须首先计算cont2。 - RayLuo
谢谢@RayLuo,但它甚至在技术上都不正确。我是在那个表格中错误地渲染的行之间赋予了意义。今天查看2.7文档时,在Firefox中orand出现在同一个单元格中,但在Opera中不是这样。orand之间的优先级差异是显而易见的(例如1 or 0 and 0(1 or 0) and 0),而andnot x之间的差异则不太明显,不像你所说的那样。我将修正我的答案以反映文档实际上所说的内容。 - Oswald Wirt

6
一些简单的例子;请注意运算符优先级(非,与,或);括号以帮助人类可读性。
a = 'apple'
b = 'banana'
c = 'carrots'

if c == 'carrots' and a == 'apple' and b == 'BELGIUM':
    print('True')
else:
    print('False')
# False

同样地:

if b == 'banana'
True

if c == 'CANADA' and a == 'apple'
False

if c == 'CANADA' or a == 'apple'
True

if c == 'carrots' and a == 'apple' or b == 'BELGIUM'
True

# Note this one, which might surprise you:
if c == 'CANADA' and a == 'apple' or b == 'banana'
True

# ... it is the same as:
if (c == 'CANADA' and a == 'apple') or b == 'banana':
True

if c == 'CANADA' and (a == 'apple' or b == 'banana'):
False

if c == 'CANADA' and a == 'apple' or b == 'BELGIUM'
False

if c == 'CANADA' or a == 'apple' and b == 'banana'
True

if c == 'CANADA' or (a == 'apple' and b == 'banana')
True

if (c == 'carrots' and a == 'apple') or b == 'BELGIUM'
True

if c == 'carrots' and (a == 'apple' or b == 'BELGIUM')
True

if a == 'apple' and b == 'banana' or c == 'CANADA'
True

if (a == 'apple' and b == 'banana') or c == 'CANADA'
True

if a == 'apple' and (b == 'banana' or c == 'CANADA')
True

if a == 'apple' and (b == 'banana' and c == 'CANADA')
False

if a == 'apple' or (b == 'banana' and c == 'CANADA')
True

2

Python没有充分的理由使用与其他编程语言不同的运算符优先级序列,包括C/C++。在Python语言参考手册的第6.16部分-运算符优先级中可以找到它,可以从https://docs.python.org/3/download.html下载(当前版本和所有其他标准文档一起),或在此处在线阅读:6.16. 运算符优先级

但是,在Python中仍然有一些东西可能会误导您: andor 运算符的结果可能与 TrueFalse 不同 - 请参见同一文档中的6.11 布尔操作


0

not > and

print(~0&0) # 0

and > or

print(0&0|1) # 1

-2

1 or 1 and 0 or 0表达式返回1。看起来我们有相同的优先级,几乎相同。


1
目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接