在 Python 中,运算符与表达式是实现计算逻辑与数据处理的基础。运算符定义数据间的操作规则,表达式则通过运算符与操作数的组合形成可执行的计算单元。从数值计算到条件判断,从数据过滤到逻辑推理,它们贯穿程序实现的全过程。本章系统阐述 Python 运算符的分类、特性及规则,结合工程实践解析表达式构建技巧,帮助读者建立清晰的计算逻辑框架,为编写高效可读的代码奠定基础。
3.1 算术运算符
算术运算符是处理数值计算的基础工具,不仅支持常规的数学运算,还针对编程场景扩展了特殊功能(如字符串重复、整除运算)。掌握其运算规则与适用场景,是实现数值处理逻辑的前提。
3.1.1 基本算术运算符
Python 支持的基础算术运算符如下(假设a = 10, b = 3):
| 运算符 | 含义 | 示例 | 结果 | 说明 |
|---|---|---|---|---|
+ | 加法 | a + b | 13 | 结果类型随操作数变化(如2 + 3.0 → 5.0) |
- | 减法 | a - b | 7 | 用于差值计算,如age - 18 |
* | 乘法 | a * b | 30 | 支持字符串重复:"hi" * 3 → "hihihi" |
/ | 除法 | a / b | 3.3333 | 始终返回浮点数(6 / 2 → 3.0) |
// | 整除 | a // b | 3 | 返回整数商,浮点数运算结果为浮点型(7.0 // 2 → 3.0) |
% | 取余 | a % b | 1 | 用于奇偶判定、周期计算(如day % 7取星期几) |
** | 幂运算 | a** b | 1000 | 乘方计算,如4 **0.5 → 2.0(开平方) |
示例:基础算术运算
# 场景:商品价格计算
price: float = 99.9
quantity: int = 3
total: float = price * quantity # 乘法运算
average: float = total / quantity # 除法运算(结果为浮点数)
discount: float = total // 10 # 整除运算(抹零处理)
print(f"总价:{total},均价:{average},折扣后:{discount}")
# 输出:总价:299.7,均价:99.9,折扣后:29.0
3.1.2 运算优先级与求值顺序
算术运算符的优先级遵循数学规则,可通过括号调整执行顺序:
- 幂运算
** - 乘、除、整除、取余
* / // % - 加、减
+ -
示例:优先级与括号的影响
result1: int = 2 + 3 * 4 # 14(先乘后加)
result2: int = (2 + 3) * 4 # 20(括号改变优先级)
此外,Python 表达式的求值顺序通常为从左到右(赋值运算符除外),但幂运算特殊,遵循从右到左的规则:
print(8 / 4 / 2) # 1.0(等价于(8/4)/2,从左到右)
print(2** 3 **2) # 64(等价于2** (3 **2),从右到左)
3.1.3 复合赋值运算符
复合赋值是 “运算 + 赋值” 的简写形式,常用于循环计数、数值累计等场景,简化代码的同时保持可读性。
常用复合赋值运算符:+=(加赋值)、-=(减赋值)、*=(乘赋值)、/=(除赋值)、//=(整除赋值)、%=(取余赋值)、**=(幂赋值)。
示例:复合赋值的应用
# 场景:订单金额累计
total_amount: float = 0.0
order_prices: list[float] = [99.9, 199.9, 299.9]
for price in order_prices:
total_amount += price # 等价于 total_amount = total_amount + price
print(f"累计金额:{total_amount:.2f}") # 输出:累计金额:599.70
3.1.4 位运算符
位运算符用于对整数的二进制位进行直接操作,在底层编程、状态压缩、算法优化等场景中广泛应用。虽然日常开发中使用频率较低,但仍是运算符体系的重要组成部分。
常用位运算符(假设a = 6即0b110,b = 3即0b011):
| 运算符 | 含义 | 示例 | 结果(二进制) | 结果(十进制) | ||
|---|---|---|---|---|---|---|
& | 按位与 | a & b | 0b010 | 2 | ||
| ` | ` | 按位或 | `a | b` | 0b111 | 7 |
^ | 按位异或 | a ^ b | 0b101 | 5 | ||
~ | 按位取反 | ~a | 0b...11111001 | -7 | ||
<< | 左移(乘 2ⁿ) | a << 1 | 0b1100 | 12 | ||
>> | 右移(除 2ⁿ) | a >> 1 | 0b11 | 3 |
示例:位运算的实际应用
# 场景1:状态压缩(用二进制位表示多个开关状态)
# 定义状态位:bit0=灯光(1=开),bit1=空调(1=开),bit2=电视(1=开)
status: int = 0b101 # 二进制101 → 灯光开、空调关、电视开
# 检查灯光是否开启(判断bit0是否为1)
is_light_on: bool = (status & 0b001) != 0
print(f"灯光状态:{is_light_on}") # 输出:灯光状态:True
# 打开空调(设置bit1为1)
status |= 0b010
print(f"更新后状态(二进制):{bin(status)}") # 输出:0b111
# 场景2:高效计算(左移1位等价于乘2,右移1位等价于整除2)
num: int = 10
print(num << 1) # 20(10 × 2¹)
print(num >> 1) # 5(10 ÷ 2¹,整除)
📌 重点提示:位运算直接操作二进制位,效率远高于算术运算,适合对性能要求高的场景(如高频交易、算法竞赛)。但可读性较低,非必要场景建议优先使用算术运算符。
3.2 比较运算符
比较运算符用于判断两个值之间的关系,返回布尔值True(真)或False(假),是条件判断、分支控制的核心工具。
3.2.1 基本比较运算符
假设a = 10, b = 3,常用比较运算符如下:
| 运算符 | 含义 | 示例 | 结果 | 说明 |
|---|---|---|---|---|
== | 等于 | a == b | False | 判断值是否相等;字符串区分大小写("A" == "a" → False) |
!= | 不等于 | a != b | True | 判断值是否不同 |
> | 大于 | a > b | True | 用于数值大小比较 |
< | 小于 | a < b | False | 与大于相反 |
>= | 大于等于 | a >= b | True | 包含等于情况 |
<= | 小于等于 | a <= b | False | 包含等于情况 |
示例:比较运算的应用
# 场景:用户年龄与分数判断
age: int = 20
score: float = 85.5
is_adult: bool = age >= 18 # 是否成年
is_excellent: bool = score > 90 # 是否优秀
print(f"成年:{is_adult},优秀:{is_excellent}") # 输出:成年:True,优秀:False
3.2.2 链式比较与类型限制
Python 支持链式比较,即用一个表达式表示多个条件的组合,等价于用and连接多个比较,简洁直观:
# 场景:判断数值是否在区间内
x: int = 5
print(1 < x < 10) # True(等价于 1 < x and x < 10)
age: int = 20
print(18 <= age <= 25) # True(判断是否为18-25岁区间)
📌 重点提示:Python 3 严格限制跨类型比较,不同类型(如int与str)直接比较会报错,避免隐式转换导致的歧义:
print(10 > "5") # 报错:TypeError(int与str无法比较)
3.3 逻辑运算符
逻辑运算符用于连接多个条件表达式,构建复合逻辑判断,包括and(与)、or(或)、not(非)三种基本运算。
3.3.1 逻辑运算符的基本用法
| 运算符 | 含义 | 示例 | 结果 | 说明 |
|---|---|---|---|---|
and | 与(且) | True and False | False | 所有条件均为真才返回真 |
or | 或 | True or False | True | 任一条件为真即返回真 |
not | 非(取反) | not True | False | 对条件结果取反 |
示例:复合条件判断
# 场景:判断用户是否满足活动参与条件
has_ticket: bool = True
is_vip: bool = False
age: int = 22
# 条件:有票 且 (是VIP 或 年龄≥18)
can_join: bool = has_ticket and (is_vip or age >= 18)
print(f"能否参与活动:{can_join}") # 输出:能否参与活动:True
3.3.2 逻辑运算的短路特性
Python 逻辑运算具有短路特性:
A and B:若A为假,直接返回A,不再计算B;A or B:若A为真,直接返回A,不再计算B。
示例:短路逻辑的应用
def check() -> bool:
print("执行检查")
return True
print(False and check()) # 输出:False(A为假,不执行check())
print(True or check()) # 输出:True(A为真,不执行check())
此外,逻辑运算符并非仅返回True/False,而是返回实际参与运算的 “真值” 或 “假值”(Python 中所有数据都有真假性):
- 假值:
0、0.0、None、空字符串""、空列表[]、空字典{}等; - 真值:非假值的所有数据(如非零数值、非空字符串、非空集合等)。
示例:非布尔返回值的应用
# 场景:设置默认值(若config为空则用默认值)
config: dict = {} # 空字典(假值)
default_config: dict = {"mode": "auto"}
active_config = config or default_config
print(active_config) # 输出:{'mode': 'auto'}(取第一个真值)
📌 重点提示:利用or设置默认值、and实现 “条件执行” 是 Python 常见技巧,但需确保代码可读性,避免过度使用导致逻辑模糊。
3.4 成员运算符与身份运算符
成员运算符用于判断元素与集合的归属关系,身份运算符用于判断变量是否指向同一对象,二者在数据校验、对象管理场景中频繁使用。
3.4.1 成员运算符
成员运算符包括in(元素在集合中)和not in(元素不在集合中),支持字符串、列表、元组、字典、集合等多种序列类型。
示例:成员运算的应用
# 场景1:检查用户权限
user_roles: list[str] = ["editor", "viewer"]
is_admin: bool = "admin" in user_roles
print(f"是否为管理员:{is_admin}") # 输出:是否为管理员:False
# 场景2:检查字符串包含关系
message: str = "I love Python programming"
has_keyword: bool = "Python" in message
print(f"包含关键词:{has_keyword}") # 输出:包含关键词:True
# 场景3:检查字典键存在(字典的in仅判断键,不判断值)
user: dict[str, int] = {"id": 1001, "age": 22}
has_email: bool = "email" in user
print(f"包含邮箱字段:{has_email}") # 输出:包含邮箱字段:False
📌 性能提示:集合(set)的in操作效率(时间复杂度O(1))远高于列表(O(n)),对需频繁判断归属的场景,建议先将列表转为集合:
# 高效:用集合存储高频查询的元素
valid_ids: set[int] = {1001, 1002, 1003}
print(1002 in valid_ids) # 快速判断
3.4.2 身份运算符
身份运算符包括is(指向同一对象)和is not(指向不同对象),用于判断变量的引用关系,与==(值相等)有本质区别:
==:判断两个对象的值是否相等;is:判断两个变量是否指向内存中的同一对象。
示例:身份运算与值比较的区别
a: list[int] = [1, 2, 3]
b: list[int] = a # b与a指向同一列表
c: list[int] = [1, 2, 3] # c是新列表(值与a相等但对象不同)
print(a == b) # True(值相等)
print(a == c) # True(值相等)
print(a is b) # True(同一对象)
print(a is c) # False(不同对象)
小整数池机制:Python 对-5~256的整数会复用对象(小整数池),导致看似独立的变量可能指向同一对象,这是身份运算的特殊场景:
x: int = 100
y: int = 100
print(x is y) # True(小整数池复用对象)
x_large: int = 1000
y_large: int = 1000
print(x_large is y_large) # False(大整数不复用)
📌 最佳实践:判断None时必须使用is None(而非== None),这是 Python 社区的规范:
value = None
print(value is None) # 推荐:True
print(value == None) # 不推荐:True(语法合法但不符合规范)
3.5 表达式综合应用与工程实践
表达式是编程逻辑的载体,合理使用运算符特性、优化表达式结构,对代码的可读性与执行效率至关重要。
3.5.1 多变量赋值与解包
Python 支持多变量并行赋值,可一次性为多个变量分配值,常用于数据解包、变量交换等场景:
# 场景1:并行赋值(变量数与值数必须一致)
name, age, is_student = "Alice", 20, True
print(f"姓名:{name},年龄:{age}") # 输出:姓名:Alice,年龄:20
# 场景2:变量交换(无需临时变量)
a, b = 10, 20
a, b = b, a # 交换a和b的值
print(f"a={a}, b={b}") # 输出:a=20, b=10
# 场景3:可迭代对象解包(提取结构化数据)
user_info: tuple = ("Bob", 22, "bob@example.com")
name, age, email = user_info # 元组解包
print(f"邮箱:{email}") # 输出:邮箱:bob@example.com
3.5.2 海象运算符(:=)
Python 3.8 引入的海象运算符(:=)允许在表达式中同时完成赋值与判断,简化代码结构,尤其适合在条件判断中复用计算结果:
# 传统写法:需计算两次len(list)
user_list: list = ["Alice", "Bob", "Charlie"]
if len(user_list) > 2:
print(f"列表过长({len(user_list)}个元素)")
# 海象运算符写法:一次计算,多次使用
if (count := len(user_list)) > 2:
print(f"列表过长({count}个元素)") # 输出:列表过长(3个元素)
适用场景:
- 条件判断中需要复用计算结果;
- 循环中控制迭代条件;
- 列表推导式中简化逻辑。
📌 使用原则:海象运算符虽能简化代码,但过度使用会降低可读性,仅在 “一次计算多次使用” 的明确场景中使用。
3.5.3 表达式的编程实践
1.** 拆分复杂表达式 ** 冗长的表达式会降低可读性,应拆分为语义化变量,使逻辑更清晰:
# 不推荐:复杂表达式难以理解
if (user.age > 18 and user.is_active and (user.balance > 1000 or user.vip)):
print("允许访问")
# 推荐:拆分后逻辑明确
is_adult: bool = user.age > 18
is_active: bool = user.is_active
has_privilege: bool = user.balance > 1000 or user.vip
if is_adult and is_active and has_privilege:
print("允许访问")
-
明确运算优先级即使运算符有默认优先级,对复杂表达式仍建议用括号明确执行顺序,避免歧义:
result: float = 2 + 3 * (4 **2) # 推荐:用括号明确优先级 # 等价于 2 + (3 * (4** 2)),结果为 50 -
避免隐蔽的类型转换逻辑运算的非布尔返回值可能导致意外结果,需确保条件判断的意图清晰:
# 风险:0是假值,但可能被误判为“不存在” count: int = 0 if count: # 等价于 if count != 0 print("有数据") else: print("无数据") # 输出:无数据(正确) # 更安全:明确判断 if count > 0: print("有数据") -
优先使用 Python 特色语法利用链式比较、成员运算等特性简化代码,符合 Python 社区的 “简洁优雅” 原则:
# 不推荐:冗余的条件判断 if score >= 60 and score <= 100: print("成绩有效") # 推荐:链式比较更简洁 if 60 <= score <= 100: print("成绩有效")