Python: 运算符全览
最后更新:2026-09-22
编程本质上就是"拿数据做运算"。第02课我们认识了变量,这一课就来学运算符——Python 提供哪些"运算能力"。算术运算、比较大小、逻辑判断、字符串拼接……学完这一课,你就能用 Python 解决很多实际问题了。
1. 算术运算符
第02课已经简单用过几个运算符,这里把它们全部列出来,系统地看看。
| 运算符 | 名称 | 示例 | 结果 | 说明 |
|---|---|---|---|---|
+ |
加法 | 5 + 3 |
8 |
也用于字符串拼接 |
- |
减法 | 5 - 3 |
2 |
也可作负号:-5 |
* |
乘法 | 5 * 3 |
15 |
也用于字符串重复 |
/ |
除法 | 5 / 3 |
1.666... |
结果永远是浮点数 |
// |
整除 | 5 // 3 |
1 |
向下取整,去掉小数部分 |
% |
取余 | 5 % 3 |
2 |
5 ÷ 3 = 1 余 2 |
** |
幂运算 | 5 ** 3 |
125 |
5 的 3 次方 |
(1) 两个值得注意的运算符
/(除法)的诡异之处:
print(4 / 2) # 输出 2.0,而不是 2
很多人第一次看到这个结果会愣一下:4 除以 2 明明等于 2,为什么 Python 输出 2.0?因为 Python 的 / 不管能不能整除,永远返回浮点数。这在编程中是为了保持结果类型的可预期性——你看到 / 就知道结果一定是 float。
//(整除)的"向下取整"陷阱:
print(7 // 3) # 输出 2(7 ÷ 3 = 2.333,取整 = 2)
print(-7 // 3) # 输出 -3 ← 可能和你想的不一样
-7 // 3 的结果是 -3,而不是 -2。因为 Python 的 // 是向下取整(floor division),不是"去掉小数部分"。"向下"在数轴上往负无穷方向走:-2.333 向下取整是 -3。如果你要的是"向零取整"(truncation),用 int(-7 / 3),结果是 -2。
// 理解为"地板除"(floor division)比"整除"更准确,因为"整除"暗示总是去掉小数部分,但负数的情况并非如此。
▶ 示例:英寸和厘米相互换算(难度⭐)
学完算术运算符,马上用它解决一个实际生活中的问题——单位换算。
▶ 试一试运行结果:
12 英寸 = 30.48 厘米
30 厘米 = 11.81 英寸
12 英寸可以分成 2 个 5 英寸,还多 2 英寸
2. 比较运算符
比较运算符用来判断两个值之间的关系,结果永远是一个布尔值(True 或 False)。它们是你写判断逻辑的基础工具。
| 运算符 | 名称 | 示例 | 结果 |
|---|---|---|---|
== |
等于 | 5 == 3 |
False |
!= |
不等于 | 5 != 3 |
True |
> |
大于 | 5 > 3 |
True |
< |
小于 | 5 < 3 |
False |
>= |
大于等于 | 5 >= 5 |
True |
<= |
小于等于 | 5 <= 3 |
False |
age = 18
print(age == 18) # True(刚好18岁)
print(age != 18) # False(并不是"不等于18")
print(age > 21) # False(还没到美国合法饮酒年龄)
print(age >= 18) # True(恰好成年,符合大于等于的条件)
(1) 链式比较
Python 支持一种简洁的写法,在其他语言中很少见:
x = 15
print(10 < x < 20) # True(相当于 10 < x and x < 20)
print(0 < x < 10) # False
这种写法比 10 < x and x < 20 更直观,更像数学中的表达方式。
(2) is 和 is not(身份比较)
严格来说 is 不是比较运算符,但它经常和 == 放在一起对比:
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True(里面装的东西一样)
print(a is b) # False(但不是同一个盒子)
print(a is c) # True(c 只是 a 的别名,指向同一个盒子)
==比的是值:"这两个变量里装的东西是不是一样的?"is比的是身份:"这两个变量是不是指向同一个对象?"
日常开发中,99% 的场景你用 == 就够了。只有判断 None 时,惯例是用 is:if result is None:。
▶ 示例:判断一个人能不能参加百米赛跑(难度⭐)
比较运算符最常见的用途就是"把某个值和某个标准比一比"。
▶ 试一试运行结果:
参赛者年龄:14
少年组(12~15):True
青年组(16~20):False
年龄已验证:True
年龄未验证:False
3. 逻辑运算符
逻辑运算符用来组合多个条件,结果也是一个布尔值。它们在 if 判断、循环条件中无处不在。
| 运算符 | 名称 | 示例 | 结果 | 说明 |
|---|---|---|---|---|
and |
与 | True and False |
False |
两个都为真才为真 |
or |
或 | True or False |
True |
至少一个为真就为真 |
not |
非 | not True |
False |
取反 |
age = 20
has_id_card = True
# and:两个条件都满足
print(age >= 18 and has_id_card) # True(既成年又有身份证)
# or:至少满足一个
print(age >= 18 or has_id_card) # True(其实两个都满足)
# not:取反
print(not has_id_card) # False(not True = False)
(1) 真值表
如果你想彻底搞懂逻辑运算,记住这三句话就够了:
| a | b | a and b | a or b | not a |
|---|---|---|---|---|
| True | True | True | True | False |
| True | False | False | True | False |
| False | True | False | True | True |
| False | False | False | False | True |
(2) 短路求值
Python 的逻辑运算符有一个重要特性:短路求值(short-circuit evaluation)。
# 对于 and:如果左边已经是 False,右边就不执行了
def say_yes():
print("say_yes 被调用了")
return True
print(False and say_yes()) # 输出 False——say_yes 根本没被执行
print(True and say_yes()) # 输出 "say_yes 被调用了" 和 True
# 对于 or:如果左边已经是 True,右边就不执行了
print(True or say_yes()) # 输出 True——say_yes 没被执行
这个特性在实际编程中非常有用:
# 只有用户存在时,才获取他的用户名——避免 None.get() 报错
user = None
username = user and user.get("name") # user 是 None(假值),短路,username = None
print(username) # None
user = {"name": "Charlie"}
username = user and user.get("name") # user 是真值,继续执行右边,username = "Charlie"
print(username) # Charlie
user and user.get("name") 这种写法在 Python 中很常见,用短路来保证"安全访问"——左边是假值就直接返回,不再执行右边可能出错的代码。
▶ 示例:判断一个数字是否"特殊"(难度⭐⭐)
把比较运算符和逻辑运算符组合起来,判断一个数字是否满足某种"特殊条件"。
▶ 试一试运行结果:
数字:49
在范围内(10~99):True
是7的倍数:True
包含数字7:False
是否特殊数字:True
数字 200:第一个条件就是 False,第二个条件不会执行——False
4. 赋值运算符
除了最基本的 =,Python 还提供了一组"复合赋值运算符",让你能一边运算一边赋值:
x = 10 # 基本赋值
x += 3 # 等价于 x = x + 3,结果是 13
x -= 2 # 等价于 x = x - 2,结果是 11
x *= 2 # 等价于 x = x * 2,结果是 22
x /= 4 # 等价于 x = x / 4,结果是 5.5
x //= 2 # 等价于 x = x // 2,结果是 2.0
x %= 2 # 等价于 x = x % 2,结果是 0.0
x **= 3 # 等价于 x = x ** 3,结果是 0.0
注意 x = 10 是整数,但 x /= 4 之后 x 变成了浮点数 5.5,因为 / 的结果永远是浮点数。如果你确实需要整数结果,用 //= 来避免类型变化。
# 自增在循环中的典型用法
score = 0
score += 10 # 加 10 分
score += 20 # 再加 20 分
score += 15 # 再加 15 分
print(f"最终得分:{score}") # 45
# 字符串也可以用复合赋值
message = "Hello"
message += " " # 加一个空格
message += "World"
print(message) # "Hello World"
x += 1 是"自增 1"的 Python 写法,在其他语言中写作 x++。Python 没有 ++ 运算符,用 += 1 就好。
5. 字符串运算符
字符串也有自己的"运算"——虽然不完全是数学意义上的运算,但写法上用的是同一个符号。
| 运算符 | 作用 | 示例 | 结果 |
|---|---|---|---|
+ |
拼接 | "Hello" + " " + "World" |
"Hello World" |
* |
重复 | "Ha" * 3 |
"HaHaHa" |
in |
判断包含 | "Py" in "Python" |
True |
not in |
判断不包含 | "xyz" not in "Python" |
True |
# 字符串拼接
first_name = "张"
last_name = "三"
full_name = first_name + last_name
print(full_name) # 输出 "Alice"
# 字符串重复——画分割线非常实用
line = "=" * 30
print(line) # 输出 30 个等号
# 成员判断(in / not in)
text = "Hello, Python!"
print("Python" in text) # True——"Python" 是 text 的一部分
print("Java" in text) # False——text 里没有 "Java"
print("Java" not in text) # True——确实是"不在里面"
+ 只能用于字符串和字符串之间,不能用于字符串和数字之间。"年龄:" + 25 会报错。需要先把数字转成字符串:"年龄:" + str(25)。* 只能用于字符串和整数之间——"AB" * 3 可以,"AB" * "CD" 不行。
▶ 示例:用字符串运算生成名片(难度⭐⭐)
在一个实际问题中同时用到字符串的 +、* 和 in。
运行结果:
生成的名片:
-------------------------
姓名:李明
职位:Python 工程师
公司:科技有限公司
-------------------------
名片中是否包含 "Python":True
名片中不包含 "Manager":True
6. 运算符优先级
数学中有"先乘除后加减",Python 也一样——运算符有优先级高低之分。
| 优先级 | 类别 | 运算符 | 说明 |
|---|---|---|---|
| 高 | 幂运算 | ** |
右结合(从右往左算) |
| ↓ | 一元运算符 | +x、-x、not |
正负号、逻辑非 |
| ↓ | 算术运算符 | *、/、//、% |
乘、除、整除、取余 |
| ↓ | 算术运算符 | +、- |
加、减 |
| ↓ | 比较运算符 | ==、!=、>、<、>=、<= |
比较大小 |
| ↓ | 逻辑运算符 | not |
逻辑非 |
| ↓ | 逻辑运算符 | and |
逻辑与 |
| ↓ | 逻辑运算符 | or |
逻辑或 |
| 低 | 赋值运算符 | =、+= 等 |
赋值 |
# 先乘除后加减
result = 2 + 3 * 4
print(result) # 14(3*4=12,再+2)
# 比较优先级低于算术——先算完算术再比较
print(2 + 3 * 4 > 10) # True(14 > 10)
# 逻辑优先级最低——先做比较,再组合逻辑
age = 20
print(age > 18 and age < 60) # True(先算 age>18 和 age<60,再做 and)
# 幂运算是右结合
print(2 ** 3 ** 2) # 512(先算 3²=9,再算 2⁹=512)
print((2 ** 3) ** 2) # 64(加了括号,先算 2³=8,再算 8²=64)
# 括号改变优先级——跟数学一样
result = (2 + 3) * 4
print(result) # 20(先算括号内的 2+3=5,再×4)
▶ 示例:按揭月供计算器(难度⭐⭐)
公式看起来复杂,拆开看无非就是算术运算加上括号控制优先级。
▶ 试一试运行结果:
贷款金额:1,000,000 元
年利率:4.5%
贷款年限:30 年
每月还款:5,066.85 元
总还款额:1,824,066.95 元
利息总额:824,066.95 元
1_000_000 中的下划线只是给人看的,Python 会忽略它。这是 Python 3.6 引入的数字可视化分隔符。优先级记不全没关系,拿不准就加括号——上面的公式加了括号后,任何人都能一眼看懂运算顺序。
7. 浮点数精度问题
这是每个学编程的人都会碰到的坑:
print(0.1 + 0.2) # 输出 0.30000000000000004
print(0.3) # 输出 0.3
print(0.1 + 0.2 == 0.3) # 输出 False ← 这竟然不是相等的!
这不是 Python 的 bug,而是计算机底层用二进制存储浮点数的固有限制。就像十进制无法精确表示 1/3 = 0.33333... 一样,二进制也无法精确表示 0.1。
(1) 什么时候要注意
- 做金融计算(涉及金额)——绝对不能直接用
float,用decimal模块 - 做比较——不要直接用
==比较浮点数,用差值判断
# 正确的浮点数比较方式
result = 0.1 + 0.2
epsilon = 1e-10 # 一个非常小的数,相当于 0.0000000001
print(abs(result - 0.3) < epsilon) # 输出 True
- 显示时取指定小数位——用 f-string 格式化
print(f"{0.1 + 0.2:.2f}") # 输出 0.30
# 一个实际例子:累加 0.1 十次
total = 0.0
for i in range(10):
total += 0.1
print(f"累加结果:{total}") # 0.9999999999999999
print(f"精确值:{total == 1.0}") # False
print(f"格式化后:{total:.2f}") # 1.00——显示没问题,别担心
== 直接比较浮点数"和"涉及金钱用 decimal 模块"这两条原则就够了。
8. 数字类型转换
Python 提供了几个函数来在不同数字类型之间转换:
# int → float
print(float(3)) # 输出 3.0
# float → int(直接截断小数部分,不是四舍五入)
print(int(3.14)) # 输出 3
print(int(-2.8)) # 输出 -2(向零取整)
# 字符串 → 数字(前提是字符串里确实是个数字)
print(int("42")) # 输出 42
print(float("3.14")) # 输出 3.14
# 数字 → 字符串
print(str(3.14)) # 输出 "3.14"
# int() 还可以指定进制
print(int("FF", 16)) # 输出 255(把十六进制的 FF 转成十进制)
print(int("1010", 2)) # 输出 10(把二进制的 1010 转成十进制)
▶ 示例:数据类型转换实战(难度⭐)
一个"输入→转换→计算→输出"的完整流程。
▶ 试一试运行结果:
你输入了:25(类型:<class 'str'>)
转换后:25(类型:<class 'int'>)
明年你就 26 岁了
你已经 25 岁了
9. 常见应用场景
- 电商价格计算:商品单价 × 数量 + 运费 - 优惠券,用 Python 表达式一行算出最终金额。满减和折扣叠加用逻辑运算符组合判断条件。
- 权限检查:判断用户是否有权操作某功能——
is_admin or (is_logged_in and has_permission)。 - 游戏伤害计算:攻击力 × 暴击倍率 - 防御力,暴击判定用比较运算符:
random.random() < crit_rate。 - 数据采样:判断一个数是不是偶数(
n % 2 == 0),或者判断是不是闰年(year % 4 == 0 and year % 100 != 0 or year % 400 == 0)。 - 时间换算:把秒数转换成"小时:分钟:秒",用整除和取余:
hours = total_seconds // 3600; minutes = (total_seconds % 3600) // 60。 - 输入验证:检查用户输入是否在有效范围内——
0 < score <= 100(链式比较),或者检查字符串包含非法字符——bad_char in username。
❓ 常见问题
== 和 is 到底有什么区别?什么场景该用哪个?== 比较的是值("里面装的东西一样吗"),is 比较的是身份("是同一个对象吗")。比如 a = [1, 2]; b = [1, 2]; c = a,则 a == b 是 True(值一样),但 a is b 是 False(两个不同的列表对象);a is c 是 True(c 只是 a 的别名)。日常开发中,99% 的场景用 == 就够了。判断是否为 None 时,惯例用 is:if result is None:。and 和 or 的短路求值在实际中有什么坑?user_input = input() or "默认值"——如果 input() 返回空字符串(假值),or 会短路直接取右边的默认值。这个写法很常见,但新手容易误读。另一个陷阱是函数调用放 and 右边——如果左边是假值,右边函数不会执行,你可能意识不到某些操作被跳过了。好习惯是:如果右边的表达式有副作用(比如文件写入、数据库更新),不要依赖短路行为,分开写。/ 和 // 到底什么时候用哪个?/。如果你只需要整数结果(比如把 7 个苹果分给 3 个人,每人分 2 个,剩下 1 个),用 // 配合 %。如果你是新手且不确定,默认用 /,至少不会丢掉精度。明确需要整数后再改成 //。2 3 2 被解析为 2 (3 2),即先算 3² = 9,再算 2⁹ = 512。如果从左到右算就是 (2³)² = 8² = 64,结果完全不同。这和数学中的习惯一致:a^b^c 的标准解释是从右上角开始算。你可以通过加括号来强制顺序:(2 3) 2 得到 64。📖 小节
- 算术运算符 7 个:
+-*///%**;/永远返回浮点数,//是向下取整 - 比较运算符 6 个:
==!=><>=<=;Python 支持链式比较如10 < x < 20 - 逻辑运算符 3 个:
and(全真才真)、or(一真即真)、not(取反);它们都被短路求值 - 字符串运算符:
+拼接、*重复、in/not in判断是否包含 - 运算优先级:
**> 一元 > 算术 > 比较 >not>and>or> 赋值。拿不准就加括号 - 浮点数无法用
==精确比较,应使用差值法abs(a - b) < epsilon
📝 作业
-
基础题(难度⭐):定义三个变量
a=10、b=3、c=20,分别计算并输出:a + b * c、(a + b) * c、a ** b、a // b、c % a、a > b and c > 15。先猜结果,再运行验证。 -
进阶题(难度⭐⭐):给定年份
year = 2026,判断它是不是闰年。闰年规则:能被 4 整除但不能被 100 整除,或者能被 400 整除。提示:year % 4 == 0判断能否被 4 整除。 -
挑战题(难度⭐⭐⭐):写一个简单的"温控系统"。给定
current_temp = 38、high_alarm = 37、low_alarm = 5。如果当前温度超过高温线或低于低温线,触发警报。如果当前温度在警戒线边缘(±2 度以内),触发"注意"而非"警报"。要求只用算术、比较和逻辑运算符实现完整的判断逻辑。提示:abs(current_temp - high_alarm) <= 2判断是否在高温警戒边缘。