学径 LearnPath

CAICP-E · Python 编程基础 / Wiki

运算优先级

一行里有好几种运算时,谁先算谁后算。

它是什么

优先级 决定先算哪一步。 不按从左到右硬算。

数学课早就有规矩:先乘除,后加减,括号最优先。 程序把这套规矩写得更长。 因为一行里不但有加减乘除,还可能有比较、并且、或者。

括号永远最优先。 看不清就加括号。 括号能让意思写在脸上。

名字从哪来

优先级的英文是 precedence,意思是「谁排在前面」。 也叫运算顺序。

算术里这套习惯很古老。 乘除先于加减,是为了少写括号,让式子更短。 不同教科书有时用口诀 PEMDAS 或「请原谅我亲爱的姨妈萨莉」来记。 细节略有出入,括号第一这件事是共同的。

编程语言各自写一张表。 Python 也有一份大家同意的先后表。 它不是魔法。 它是说明书,免得你心里的顺序和电脑的顺序打架。

它怎么工作

可以记一个从先到后的短表:

  1. 括号 ()
  2. 乘方 **
  3. 乘、除、整除、取余 * / // %
  4. 加、减 + -
  5. 比较 > < == != >= <=,以及 in
  6. not
  7. and
  8. or

赋值 = 很靠后。 通常先把右边算完,再放进左边的 变量

python
print(3 + 2 * 4)      # 11
print((3 + 2) * 4)    # 20

第一行先乘后加。 第二行括号改了顺序。

逻辑也一样:

python
print(True or False and False)         # True
print((True or False) and False)       # False

andor 先算。

复合运算就是把 算术、比较、逻辑 叠在一行。

python
n = 8
print(n > 0 and n % 2 == 0)

% 先算。 再比较。 再 and。 所以这是在问:n 是正数,并且是偶数吗?

同一级的运算,多半从左到右。 乘方 ** 比较特别,从右到左:2 ** 3 ** 22 ** 9,不是 8 ** 2。 看不清,仍然加括号。

生活里在哪里

  • 买东西:3 件单价 2 元,再加 4 元运费。先算 3 * 2,再加 4。
  • 做菜:先洗再切再炒,顺序错了,菜就坏了。
  • 排队:VIP 窗口不是插队,是另一套「谁先」的规则。
  • 交通:消防车比普通车优先。优先级就是「谁先走」。

口算时如果你会先乘后加,就已经在用优先级了。 程序不过是把同一件事写进语言。

和相近概念的差别

优先级不是一种新运算。 它不算出新的符号,只安排已有符号的上场顺序。

缩进 管的是上下结构:谁属于谁。 优先级管的是一行之内:谁先算完。

括号在这里是「先算我」。 函数调用的括号是「干活」。 两种括号长得像,任务不同。

and 的优先级高于 or,不等于 and 更重要。 只是默认先把它算完。 你可以用括号改这件事。

常见误会

误会 1:以为一律从左算到右。

3 + 2 * 4 不是 5 * 4

误会 2:一长串比较和逻辑不拆步骤。

拆开,或加括号。 电脑按表算,不按你心里的停顿算。

误会 3:括号不成对。

少一个,常变成 SyntaxError。 见 调试

误会 4:==and 后算,所以可以随便写。

短表能帮你,但不能代替括号。 给以后读代码的人看,括号往往更友善。

误会 5:优先级能让错误的类型自动变对。

"3" + 1 仍然报错。 先 转换,再谈谁先算。

想知道更多

  • 书:潘洪波《小学生 Python 趣味编程》(算式里加括号,把「谁先算」写在脸上)。
  • 书:埃里克·马瑟斯《Python 编程:从入门到实践》(算术和条件出现时,会提醒你用括号把意思写清楚)。

未登录时不会保存学习进度