Python运算符优先级和结合性一览表
优先级和结合性是Python表达式中比较重要的两个概念,它们决定了先执行表达式中的哪一部分。
Python运算符优先级
所谓优先级,就是当多个运算符同时出现在一个表达式中时,先执行哪个运算符。
例如对于表达式a+b*c,Python会先计算乘法再计算加法;b*c的结果为8,a+8的结果为24,所以d最终的值也是24。先计算*再计算+,说明*的优先级高于+。
Python支持几十种运算符,被划分成将近二十个优先级,有的运算符优先级不同,有的运算符优先级相同,请看下表。
表1 Python运算符优先级和结合性一览表
运算符说明 | Python运算符 | 优先级 | 结合性 | 优先级顺序 |
---|---|---|---|---|
小括号 | ( ) | 19 | 无 | 高 ︿ | | | | | | | | | | | | | | | | | | | | | | 低 |
索引运算符 | x[i] 或 x[i1: i2 [:i3]] | 18 | 左 | |
属性访问 | x.attribute | 17 | 左 | |
乘方 | ** | 16 | 右 | |
按位取反 | ~ | 15 | 右 | |
符号运算符 | +(正号)、-(负号) | 14 | 右 | |
乘除 | *、/、//、% | 13 | 左 | |
加减 | +、- | 12 | 左 | |
位移 | >>、<< | 11 | 左 | |
按位与 | & | 10 | 右 | |
按位异或 | ^ | 9 | 左 | |
按位或 | | | 8 | 左 | |
比较运算符 | ==、!=、>、>=、<、<= | 7 | 左 | |
is 运算符 | is、is not | 6 | 左 | |
in 运算符 | in、not in | 5 | 左 | |
逻辑非 | not | 4 | 右 | |
逻辑与 | and | 3 | 左 | |
逻辑或 | or | 2 | 左 | |
逗号运算符 | exp1, exp2 | 1 | 左 |
结果表1中的运算符优先级,我们尝试分析下面表达式的结果:
4+4<<21复制代码类型:[python]
+的优先级是12,<<的优先级是11,+的优先级高于<<,所以先执行4+4,得到结果8,再执行8<<2,得到结果32,这也是整个表达式的最终结果。
像这种不好确定优先级的表达式,我们可以给子表达式加上(),也就是写成下面的样子:
(4+4) << 21复制代码类型:[python]
这样看起来就一目了然了,不容易引起误解。
当然,我们也可以使用()改变程序的执行顺序,比如:
4+(4<<2)1复制代码类型:[python]
则先执行4<<2,得到结果16,再执行4+16,得到结果20。
虽然Python运算符存在优先级的关系,但我不推荐过度依赖运算符的优先级,这会导致程序的可读性降低。因此,我建议读者:
不要把一个表达式写得过于复杂,如果一个表达式过于复杂,可以尝试把它拆分来书写。
不要过多地依赖运算符的优先级来控制表达式的执行顺序,这样可读性太差,应尽量使用()来控制表达式的执行顺序。
Python运算符结合性
所谓结合性,就是当一个表达式中出现多个优先级相同的运算符时,先执行哪个运算符:先执行左边的叫左结合性,先执行右边的叫右结合性。
例如对于表达式对于100/25*16,/和*的优先级相同,应该先执行哪一个呢?这个时候就不能只依赖运算符优先级决定了,还要参考运算符的结合性。/和*都具有左结合性,因此先执行左边的除法,再执行右边的乘法,最终结果是64。
Python中大部分运算符都具有左结合性,也就是从左到右执行;只有**乘方运算符、单目运算符(例如not逻辑非运算符)、赋值运算符和三目运算符例外,它们具有右结合性,也就是从右向左执行。表1中列出了所有Python运算符的结合性。
总结
当一个表达式中出现多个运算符时,Python会先比较各个运算符的优先级,按照优先级从高到低的顺序依次执行;当遇到优先级相同的运算符时,再根据结合性决定先执行哪个运算符:如果是左结合性就先执行左边的运算符,如果是右结合性就先执行右边的运算符。