4、运算符与表达式:从基础运算到复杂求值

运算符是Python程序中构建表达式的基本“积木”,而表达式则是程序进行数据加工与逻辑判断的核心载体。无论是编写一个简单的数值计算器,还是实现复杂的人工智能算法,都离不开对运算符的精准运用。本章将系统梳理Python中的七大类运算符,深入解析运算符的优先级与结合性,并通过实战案例帮助您建立从“认识符号”到“熟练求值”的完整能力链路。

Python 运算符全景图与表达式求值路径 表达式 Expression 算术运算符 比较运算符 逻辑运算符 赋值运算符 位运算符 成员运算符 身份运算符 优先级(高→低)与结合性(左→右) ** → 正负号 → * / // % → + - → 移位 → & → ^ | → 比较 → not → and → or → 赋值 最终求值:遵循优先级 → 结合性 → 短路规则

4.1 算术运算符与赋值运算符:程序计算的基础

核心原理

算术运算符用于执行数学运算,Python支持加(+)、减(-)、乘(*)、除(/)、整除(//)、取余(%)和幂运算(**)。其中/的结果始终为浮点数,而//向下取整,%返回余数。赋值运算符=用于将右侧的值绑定到左侧变量,复合赋值运算符(如+=、*=)则先执行运算再赋值,简化代码书写。

判断方法与操作流程

  • 整除与取余的配合:divmod(a, b)可同时返回商和余数,常用于时间换算、分页计算。
  • 复合赋值展开:x += 5等价于x = x + 5,但前者仅计算一次变量地址,效率略高。
  • 链式赋值:a = b = c = 0将同一对象赋给多个变量,适用于初始化。

案例拆解:商品折扣计算器

某电商平台需计算商品折后价:原价price = 299,折扣discount = 0.85,满200减30。使用表达式final_price = price * discount - 30,结果为224.15。若改用整除//计算可购买数量:预算budget = 1000,count = budget // final_price得4件,剩余budget % final_price为103.4元。此案例展示了算术运算符在真实业务中的组合应用。

💡 经验提醒:浮点数运算存在精度误差(如0.1 + 0.2 != 0.3),涉及金额时建议使用Decimal模块或先转为整数分再计算。

4.2 比较运算符与逻辑运算符:构建判断条件

核心原理

比较运算符(>、<、>=、<=、==、!=)返回布尔值True或False。逻辑运算符and、or、not用于组合多个条件,遵循短路求值规则:and左侧为False时不再计算右侧,or左侧为True时不再计算右侧。这一特性可用于避免无效计算或空值访问。

判断方法与操作流程

运算符含义示例结果
==值相等5 == 5.0True
is身份相等5 is 5True(小整数缓存)
and全真才真True and FalseFalse
or一真即真False or TrueTrue
not取反not TrueFalse

实战场景:用户登录验证

系统要求用户名非空且密码长度≥6位:if username != "" and len(password) >= 6:。若用户名输入为空,and短路直接返回False,不会执行len(password),避免潜在错误。若使用or判断管理员权限:if user.role == "admin" or user.is_superuser:,当第一个条件满足时跳过第二个判断,提升效率。

⚠️ 常见误区:不要混淆==(值比较)与is(身份比较)。对于列表、字典等可变对象,==比较内容,is比较内存地址。例如[1,2] == [1,2]为True,但[1,2] is [1,2]为False。

4.3 位运算符与成员/身份运算符:深入底层与容器操作

核心原理

位运算符直接操作整数二进制位,包括按位与(&)、或(|)、异或(^)、取反(~)、左移(<<)和右移(>>)。成员运算符in和not in用于判断元素是否存在于序列(字符串、列表、元组、字典键)中。身份运算符is和is not判断两个变量是否引用同一对象。

判断方法与操作流程

  • 位运算技巧:x & 1判断奇偶(结果为1为奇数),x << 1等价于乘以2,x >> 1等价于整除2。
  • 成员判断效率:对于列表使用in是O(n)复杂度,而集合或字典键为O(1),大数据量时优先转换。
  • 身份判断场景:检查变量是否为None时使用is None,而非== None。

案例拆解:权限系统位掩码

某系统用4位二进制表示权限:读(1)、写(2)、执行(4)、管理(8)。用户权限perm = 5(二进制0101)表示可读可执行。判断是否有写权限:if perm & 2:,结果为0则无权限。设置权限:perm |= 2添加写权限,perm &= ~2移除写权限。此案例展示了位运算在资源受限环境下的高效性。

🔍 深度对比:成员运算符in在字典中默认检查键,若需检查值需使用value in dict.values()。身份运算符is对整数在-5到256范围内因缓存机制可能返回True,超出范围则返回False,务必谨慎使用。

4.4 运算符优先级与结合性:表达式求值的核心规则

核心原理

Python定义了严格的运算符优先级,从高到低依次为:幂运算** → 正负号 → 算术乘除 → 算术加减 → 移位 → 位与 → 位异或 → 位或 → 比较 → 逻辑非 → 逻辑与 → 逻辑或 → 赋值。结合性决定同级运算符的执行顺序,大多数运算符为左结合(从左到右),但**和赋值运算符为右结合(从右到左)。

判断方法与操作流程

  1. 查表定位:遇到复杂表达式,先找到优先级最高的运算符,将其视为一个整体。
  2. 括号优先:使用括号明确运算顺序,避免依赖记忆优先级。
  3. 结合性判断:对于a - b - c,左结合计算(a - b) - c;对于a ** b ** c,右结合计算a ** (b ** c)。

表达式求值实战

# 复杂表达式逐步拆解
result = 2 + 3 * 4 ** 2 - 8 / 2 % 3
# 步骤1: 4 ** 2 = 16
# 步骤2: 3 * 16 = 48
# 步骤3: 8 / 2 = 4.0, 4.0 % 3 = 1.0
# 步骤4: 2 + 48 - 1.0 = 49.0
print(result)  # 输出 49.0

此案例展示了优先级如何决定计算顺序:先幂运算,再乘除取余,最后加减。若误写为(2 + 3) * 4 ** 2,结果变为80,差异显著。

⚠️ 风险提示:逻辑运算符and和or的优先级低于比较运算符,因此a > 0 and b > 0实际解析为(a > 0) and (b > 0),无需额外括号。但赋值运算符优先级最低,x = a > 0先计算比较再赋值。

4.5 综合案例:学生成绩评定系统

背景与目标

某学校需开发成绩评定模块:输入学生三门课程成绩(百分制),输出总分、平均分、最高分、是否优秀(平均≥85且无不及格)、是否需补考(任一科<60)。要求使用本章全部运算符类型。

实现过程

# 输入成绩
chinese = 88; math = 92; english = 57
# 算术运算
total = chinese + math + english
average = total / 3
max_score = max(chinese, math, english)
# 比较与逻辑运算
is_excellent = average >= 85 and all(s >= 60 for s in [chinese, math, english])
needs_makeup = any(s < 60 for s in [chinese, math, english])
# 位运算判断奇偶(示例)
is_total_even = (total & 1) == 0
# 成员运算
passed_subjects = [s for s in [chinese, math, english] if s in range(60, 101)]
# 身份运算
has_extra = max_score is not None
print(f"总分:{total}, 平均:{average:.1f}, 最高:{max_score}")
print(f"优秀:{is_excellent}, 补考:{needs_makeup}, 总分偶数:{is_total_even}")

结果与复盘

输出:总分237,平均79.0,最高92,优秀False(因英语不及格),补考True。此案例综合运用了算术(总分/平均)、比较(≥85)、逻辑(and/or)、成员(in range)、身份(is not)等运算符。复盘发现:all()和any()内部隐含短路逻辑,与and/or行为一致;位运算判断奇偶在性能敏感场景比取模%更快。

📌 总结复盘:掌握运算符优先级是写出正确表达式的前提,建议遵循“能加括号就加括号”原则。同时注意:and/or返回的是操作数而非布尔值(如0 or 5返回5),这在赋值时可能产生意外结果,需结合上下文判断。