Python运算符一览表:算术、比较、逻辑、位运算及优先级详解
一、Python 运算符体系全景概览
Python 语言中的运算符根据其操作数类型和运算目标,可分为六大核心类别:算术运算符用于数值代数计算;比较运算符用于量值关系断言并返回布尔值;逻辑运算符用于布尔命题连接与条件短路控制;位运算符直接作用于整型数据的二进制补码;赋值运算符负责将计算结果绑定至变量;身份与成员运算符则用于对象指针地址一致性与集合包含关系的判定。
二、算术运算符与数值截断机制
算术运算符用于执行标准数学代数计算。除了常规的加、减、乘之外,Python 在除法和幂次运算上具有独特性质。
| 运算符 | 名称 | 语法描述 | 示例 | 运算结果 |
|---|---|---|---|---|
+ |
加法 | 两数相加,亦可用于序列拼接 | 7 + 3 |
10 |
- |
减法 | 左操作数减去右操作数,或一元负号 | 7 - 3 |
4 |
* |
乘法 | 两数相乘,亦可用于序列重复 | 7 * 3 |
21 |
/ |
真除法 | 浮点除法,结果恒为 float 类型 | 7 / 2 |
3.5 |
// |
整除(地板除) | 向下取整除法,返回不大于商的最大整数 | 7 // 2 |
3 |
% |
模运算(求余) | 返回除法后的余数,满足 r = a - (a // b) * b |
7 % 2 |
1 |
** |
幂运算 | 求左操作数的右操作数次幂 | 2 ** 3 |
8 |
关键差异解析:真除法 / 与地板除 // 及负数取模
在许多语言(如 C/Java)中,两整数相除会默认截断小数部分。而在 Python 3 中,/ 是真除法,即使两个整数能整除(如 4 / 2),其返回结果依然是浮点数 2.0。
当涉及负数整除与求余时,Python 遵循向下取整(Floor Division)原则,向负无穷方向取整,而非向零截断:
# 正数情况
print(7 // 2) # 输出 3
print(7 % 2) # 输出 1 (7 = 3 * 2 + 1)
# 负数整除:-7 / 2 实际为 -3.5,向下取整为 -4
print(-7 // 2) # 输出 -4
# 负数求余:按照 公式 r = a - (a // b) * b
# -7 - (-4 * 2) = -7 - (-8) = 1
print(-7 % 2) # 输出 1
这一特性保证了对于正除数 b > 0,余数 a % b 始终满足 0 <= r < b,在构建循环索引或哈希散列时具有非常良好的数学一致性。
三、比较运算符与链式比较语法
比较运算符用于比对两个操作数的大小或等价状态,运算结果恒为布尔值(True 或 False)。
| 运算符 | 名称 | 判定条件 | 示例 | 返回结果 |
|---|---|---|---|---|
== |
等于 | 判断两操作数的值是否相等 | 5 == 5.0 |
True |
!= |
不等于 | 判断两操作数的值是否不相等 | 5 != 6 |
True |
> |
大于 | 左侧数值是否严格大于右侧 | 10 > 5 |
True |
< |
小于 | 左侧数值是否严格小于右侧 | 3 < 8 |
True |
>= |
大于等于 | 左侧数值是否大于或等于右侧 | 5 >= 5 |
True |
<= |
小于等于 | 左侧数值是否小于或等于右侧 | 4 <= 5 |
True |
1 < x < 10 的链式比较表达式。该形式在语义上等价于 1 < x and x < 10,但关键差异在于:中间的操作数 x 只会被求值一次。这避免了重复计算开销,也防止了中间表达式含有副作用时导致的不确定性。
四、逻辑运算符与短路求值机制
Python 提供了三个逻辑运算符:and(逻辑与)、or(逻辑或)和 not(逻辑非)。与其他部分语言不同,Python 中的 and 和 or 并不强制将操作数转换为布尔类型后再返回,而是直接返回决定表达式真假结果的那个操作数原值。
| 运算符 | 语义规则 | 求值逻辑 | 典型示例 | 返回结果 |
|---|---|---|---|---|
x and y |
逻辑与 | 若 x 为假,直接返回 x;否则对 y 求值并返回 y |
0 and "hello""hi" and [1, 2] |
0[1, 2] |
x or y |
逻辑或 | 若 x 为真,直接返回 x;否则对 y 求值并返回 y |
"admin" or "guest"[] or "default" |
"admin""default" |
not x |
逻辑非 | 若 x 为真返回 False,若 x 为假返回 True |
not 0not "text" |
TrueFalse |
短路求值在工程实践中有两大重要用途:
- 防御式属性访问:
if user is not None and user.is_authenticated:。若user为空,后续方法调用直接短路跳过,避免抛出AttributeError。 - 默认值绑定:
timeout = config_timeout or 30。当配置未指定或为None/0时,自动采纳默认回退值。
五、位运算符与底层二进制操作
位运算符将整数作为二进制位序列进行按位逻辑处理。在 Python 中,整数是任意精度的,其负数在位运算中表现为理论上具有无限长符号扩展的二进制补码(Two's Complement)形式。
| 运算符 | 名称 | 逐位规则 | 以 a=12, b=5 计算 | 十进制结果 |
|---|---|---|---|---|
& |
按位与 | 同为 1 时结果为 1,否则为 0 | 12 & 5 (0b1100 & 0b0101) |
4 (0b0100) |
| |
按位或 | 只要有一位为 1 结果即为 1 | 12 | 5 (0b1100 | 0b0101) |
13 (0b1101) |
^ |
按位异或 | 位相同为 0,位不同为 1 | 12 ^ 5 (0b1100 ^ 0b0101) |
9 (0b1001) |
~ |
按位取反 | 对位逐位翻转(0变1,1变0),恒等于 -(x + 1) |
~12 |
-13 |
<< |
左移 | 各二进位向左移动指定位数,低位补0,相当于 x * (2**n) |
12 << 2 |
48 |
>> |
右移 | 各二进位向右移动指定位数,高位补符号位,相当于 x // (2**n) |
12 >> 2 |
3 |
六、赋值、身份与成员运算符
1. 赋值与复合赋值运算符
Python 使用 = 进行变量名称与对象的引用绑定。复合赋值运算符(如 +=, -=, *=, &=)在更新数值变量时相当于重新赋值,但在可变对象(如列表)上,+= 会调用就地修改方法 __iadd__,不会分配新的内存对象。
此外,Python 3.8 引入了海象运算符(Walrus Operator):=,允许在表达式内部完成变量赋值,例如:
# 海象运算符示例:赋值并同时执行条件判断
while (chunk := file.read(1024)):
process_data(chunk)
2. 身份运算符:is 与 == 的关键差异
很多初学者容易混淆 is 与 ==。两者的核心差异在于比较的底层维度完全不同:
==比较运算符:调用对象的__eq__()方法,核对两者的内容与值是否等价。is身份运算符:直接比较两个对象的内存地址(Memory Identity),等价于id(a) == id(b),判断它们是否为同一个对象。
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True: 列表内容完全相同
print(a is b) # False: a 和 b 是内存中独立分配的两个列表对象
# 针对单例对象 None,规范要求必须使用 is
if val is None:
pass
3. 成员运算符:in 与 not in
用于测试某个元素是否存在于指定的容器序列(如字符串、列表、元组、集合、字典)中。在字典中使用 in 时,默认检测的是键(Keys)是否存在。
需要注意不同数据结构的查询效率差异:在 list / tuple 中使用 in 是 $O(n)$ 线性扫描;而在 set / dict 中使用 in 是基于哈希表的 $O(1)$ 常数时间查询。
七、运算符优先级与结合性全览表
当多个运算符出现在同一个表达式中时,Python 根据严格的优先级(Precedence)和结合性(Associativity)决定执行次序。表中位置越靠前,优先级越高。同一行的运算符具有相同优先级,通常按照从左至右结合(幂运算 ** 为右结合)。
| 优先级顺序 | 运算符 | 说明与类别 | 结合方向 |
|---|---|---|---|
| 1(最高) | ( ) |
圆括号分组 | 从内向外 |
| 2 | ** |
指数运算(幂) | 从右向左(右结合) |
| 3 | +x, -x, ~x |
一元正号、一元负号、按位取反 | 从右向左 |
| 4 | *, /, //, % |
乘法、浮点除、整除、取模 | 从左向右 |
| 5 | +, - |
加法、减法 | 从左向右 |
| 6 | <<, >> |
按位左移、右移 | 从左向右 |
| 7 | & |
按位与 | 从左向右 |
| 8 | ^ |
按位异或 | 从左向右 |
| 9 | | |
按位或 | 从左向右 |
| 10 | ==, !=, >, >=, <, <=, is, is not, in, not in |
比较运算符、身份运算符、成员运算符 | 链式结合 |
| 11 | not |
逻辑非 | 从右向左 |
| 12 | and |
逻辑与 | 从左向右 |
| 13 | or |
逻辑或 | 从左向右 |
| 14 | if - else |
条件表达式(三元运算) | 从右向左 |
| 15 | := |
海象运算符(赋值表达式) | 从右向左 |
| 16(最低) | =, +=, -= 等 |
赋值及复合赋值 | 从右向左 |
指数运算的右结合性特征
大多数二元运算符都是左结合的,例如 10 - 4 - 2 等价于 (10 - 4) - 2 = 4。而幂运算符 ** 具有从右向左结合的特征:
# 表达式: 2 ** 3 ** 2
# 按照右结合规则,先计算 3 ** 2 = 9,再计算 2 ** 9 = 512
result = 2 ** 3 ** 2
print(result) # 输出 512,而不是 (2**3)**2 = 64
八、复杂表达式求值推导实例
为了验证优先级规则在混合表达式中的运作方式,我们分析以下包含算术、比较、逻辑非、逻辑与、逻辑或的复杂语句:
result = 3 + 4 * 2 > 10 and not 5 < 2 or False
根据 Python 官方规范的优先级层次,计算引擎按照如下五个推导阶段完成表达式归约:
九、工程开发中的最佳实践与避坑要点
-
优先使用圆括号明确意图:尽管 Python 具备严谨的优先级定义,但在团队开发中,长表达式依赖默认优先级会极大增加阅读成本并诱发微小 Bug。编写类似
(a + b) * c或(x > 0) and (y < 10)能够显著提升代码自解释能力。 -
严格区分
is与==:检查是否为单例常量(如None、True、False)时,一律使用is和is not;检查内容是否相等时,使用==。切勿在比较普通整数或字符串时依赖is,因为小整数对象池(-5 至 256)的缓存属于解释器实现细节,非语言语义保证。 -
警惕浮点数比较陷阱:由于底层 IEEE 754 二进制浮点表示精度限制,
0.1 + 0.2 == 0.3返回False。在涉及浮点数大小相等比对时,应使用标准库math.isclose(a, b)代替直接的==。 -
适度使用逻辑短路:利用
or设置默认值(如name = input_name or "Guest")简洁优雅,但需注意如果合法有效值本身是 falsy 值(例如空字符串""或数字0),该写法会错误触发默认值替换。此时应改写为明确的name = input_name if input_name is not None else "Guest"。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













