🎯 学习目标
- 掌握算术、赋值、比较、逻辑、成员、身份、位运算符的用法
- 理解
/与//、%在负数时的行为 - 彻底搞懂
and/or的短路求值与返回值规则 - 会写 Python 风格的链式比较与三元表达式
- 了解海象运算符
:=与位运算的典型用途 - 能依据优先级表判断复杂表达式的计算顺序
1算术运算符
| 运算符 | 含义 | 示例 | 结果 |
|---|---|---|---|
+ | 加法(字符串/列表还可拼接) | 3 + 2 | 5 |
- | 减法 / 负号 | 3 - 2 | 1 |
* | 乘法(字符串可重复) | "ab" * 3 | 'ababab' |
/ | 真除法(结果必为 float) | 7 / 2 | 3.5 |
// | 整除(向下取整) | 7 // 2 | 3 |
% | 取余(模运算) | 7 % 2 | 1 |
** | 幂运算 | 2 ** 10 | 1024 |
# 整除与取余满足关系:a == (a // b) * b + (a % b)
print(-7 // 2) # -4 向负无穷方向取整(不是 -3!)
print(-7 % 2) # 1 由上面的恒等式推出
print(7 // -2) # -4
print(7 % -2) # -1
# % 的实用场景
print(10 % 3) # 1:判断整除、周期性问题
print("成绩:%5d" % 88) # % 还可用于旧式字符串格式化
print(divmod(17, 5)) # (3, 2):一次拿到商和余数
% 常见用途:判断奇偶 n % 2 == 0、判断整除 n % 5 == 0、秒数转"分:秒"f"{s // 60}:{s % 60:02d}"、环形队列取索引。
2赋值运算符
x = 10 # 基本赋值
x += 3 # 等价 x = x + 3 → 13
x -= 1 # x = x - 1 → 12
x *= 2 # 24
x /= 4 # 6.0(/= 后变 float)
x //= 2 # 3.0
x %= 2 # 1.0
x **= 3 # 1.0
# 其他语言里的 x++ / x-- 在 Python 中【不存在】,请写 x += 1
复合赋值对可变对象有特殊行为:lst += [4] 是原地修改列表;而 lst = lst + [4] 是生成新列表。这一差异在函数传参、默认参数场景会引发隐蔽 bug,第 6、7 章会再遇到。
海象运算符 :=(Python 3.8+)
海象运算符(walrus operator)在表达式内部完成"赋值 + 使用",常用于减少重复计算:
# 传统写法:先计算再判断
line = input("输入:")
while line != "quit":
print("你输入了", line)
line = input("输入:")
# 海象写法:输入、判断二合一
while (line := input("输入:")) != "quit":
print("你输入了", line)
# 避免重复调用 len()
text = "hello world"
if (n := len(text)) > 5:
print(f"文本长度 {n} 超过 5")
3比较运算符
| 运算符 | 含义 | 示例 |
|---|---|---|
== | 值相等 | 1 == 1.0 → True |
!= | 不相等 | "a" != "b" |
> / < | 大于 / 小于 | 3 > 2 |
>= / <= | 大于等于 / 小于等于 | 5 >= 5 |
比较运算的结果一定是 bool(True/False)。Python 支持极具可读性的链式比较:
score = 75
print(60 <= score < 90) # True,数学写法直接用
# 等价于 (60 <= score) and (score < 90),但 score 只求值一次
print(1 < 2 < 3) # True
print(1 < 2 == 2) # True
# 字符串按字典序逐字符比较(比 Unicode 码点)
print("apple" < "banana") # True
print("abc" < "abd") # True
print("a" < "A") # False(小写字母码点更大:ord('a')=97 > ord('A')=65)
4逻辑运算符:and / or / not
True and False # False 与:两者都真才真
True or False # True 或:任一为真即真
not True # False 非:取反
age = 25
print(age >= 18 and age <= 60) # True
print(not (age < 18)) # True
4.1 短路求值(重要)
Python 的 and、or 会从左到右计算,一旦结果确定就立即停止,右侧表达式根本不会执行:
# and:左假即假,右边短路不执行
False and print("不会打印")
# or:左真即真,右边短路不执行
True or print("不会打印")
# 经典保护:先判断非空,再取下标,避免 IndexError
data = []
if data and data[0] > 0:
print("有正数")
# 除零保护
b = 0
if b != 0 and 10 / b > 1:
print("安全")
4.2 and/or 返回的不一定是布尔值
这是 Python 与很多语言不同的设计:and/or 返回的是参与运算的某个对象本身,而不是强制变成 True/False:
# x and y:x 为假 → 返回 x;否则返回 y
print(0 and "hello") # 0
print(3 and "hello") # hello
# x or y:x 为真 → 返回 x;否则返回 y
print("a" or "b") # a
print("" or "默认值") # 默认值
print(not "abc") # False(not 会强制返回 bool)
print(not "") # True
利用这一特性可以写简洁的默认值惯用法(但语义不清时不要滥用):
username = input("昵称(留空则为游客):")
name = username or "游客" # 留空(""为假)时回退到"游客"
print("欢迎," + name)
5成员运算符与身份运算符
# in / not in:判断"是否包含",适用于字符串、列表、元组、字典、集合
print("py" in "python") # True
print(3 in [1, 2, 3]) # True
print("name" in {"name": "张三"}) # True(字典判断的是键)
print(5 not in (1, 2, 3)) # True
# is / is not:判断是否同一个对象(身份比较)
x = None
print(x is None) # 判断 None 的标准写法
a = b = [1]
print(a is b) # True
# == 比值;is 比身份
print([1, 2] == [1, 2]) # True
print([1, 2] is [1, 2]) # False
规则:值比较一律 ==;只有与单例对象比较时用 is——最常见的就是 is None / is not None。不要写 x is 100 这类代码(小整数缓存是 CPython 实现细节)。
6位运算符(了解为主)
位运算直接操作整数的二进制位,在算法题、权限标志、嵌入式/高性能场景使用:
| 运算符 | 含义 | 示例(以 5=101₂、3=011₂ 为例) |
|---|---|---|
& | 按位与 | 5 & 3 → 1(001) |
| | 按位或 | 5 | 3 → 7(111) |
^ | 按位异或 | 5 ^ 3 → 6(110,相同为0不同为1) |
~ | 按位取反 | ~5 → -6 |
<< | 左移(低位补0) | 1 << 3 → 8(等于 ×8) |
>> | 右移 | 8 >> 2 → 2(等于 //4) |
# 实用:不用乘除做 2 的倍数运算(高性能场景)
print(1024 << 1) # 2048
print(1024 >> 1) # 512
# 判断奇偶:看最低位
print((n := 7) & 1) # 1 奇数;0 偶数
# 权限标志:用不同二进制位组合权限
READ, WRITE, EXEC = 1, 2, 4
perm = READ | WRITE # 授予 读+写 = 3
print(bool(perm & READ)) # True:检查是否有读权限
7三元表达式
Python 的条件表达式读作"真值 if 条件 else 假值",用于一行完成简单的二选一:
score = 58
result = "及格" if score >= 60 else "不及格"
print(result) # 不及格
# 等价于:
# if score >= 60:
# result = "及格"
# else:
# result = "不及格"
print(max(3, 9)) # 9
# 手写一个 max 也可以用三元表达
bigger = a if (a := 3) > (b := 9) else b
print(bigger) # 9
三元表达式只适合简短的二选一;分支逻辑复杂时请老老实实写 if/else,可读性优先。
8运算符优先级
优先级决定"先算谁",下表从高到低列出常用运算符(完整版可查官方文档):
| 优先级 | 运算符 | 说明 |
|---|---|---|
| 高 | ** | 幂运算(右结合:2**3**2 == 2**9) |
| ↓ | ~ + - | 按位取反、正负号 |
* / // % | 乘除类 | |
+ - | 加减 | |
<< >> | 移位 | |
& | 按位与 | |
^ | | 异或、或 | |
== != > < >= <= is in | 比较/身份/成员 | |
not | 逻辑非 | |
and | 逻辑与 | |
| 低 | or | 逻辑或 |
print(2 + 3 * 4) # 14(先乘后加)
print(True or False and False) # True(and 优先级高于 or)
# 等价 True or (False and False)
# 不要靠背优先级!复杂表达式请主动加括号,既正确又易读
x = 2 + 3 * 4 ** 2 # 50:** → * → +
y = 2 + (3 * (4 ** 2)) # 50,一目了然
工程建议:能用括号明确意图时就加括号。代码是写给人看的,不要让同事(以及三个月后的自己)去背优先级表。
9本章小结与练习
📌 关键结论
/总返回 float;//向下取整,负数方向要小心。- 链式比较
0 <= x < 100是 Python 招牌写法。 and/or会短路,并返回参与运算的对象本身;not返回布尔值。- 比值用
==,判空用is None,判包含用in。 - Python 没有
++/--;三元表达式是"值 if 条件 else 值"。
练习1:print(0 or 5 and 3) 输出什么?
练习2:不使用 if,一行代码判断变量 n 是否为 0~100(含)之间的偶数。
print(0 <= n <= 100 and n % 2 == 0)。链式比较判断区间,% 判奇偶,and 组合。