Python: 运算符全览

编程本质上就是"拿数据做运算"。第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) 两个值得注意的运算符

/(除法)的诡异之处:

PYTHON
print(4 / 2)    # 输出 2.0,而不是 2

很多人第一次看到这个结果会愣一下:4 除以 2 明明等于 2,为什么 Python 输出 2.0?因为 Python 的 / 不管能不能整除,永远返回浮点数。这在编程中是为了保持结果类型的可预期性——你看到 / 就知道结果一定是 float

//(整除)的"向下取整"陷阱:

PYTHON
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)比"整除"更准确,因为"整除"暗示总是去掉小数部分,但负数的情况并非如此。

▶ 示例:英寸和厘米相互换算(难度⭐)

学完算术运算符,马上用它解决一个实际生活中的问题——单位换算。

PYTHON
# 英寸转厘米:1 inch = 2.54 cm

# 一个标准尺子的长度
inches = 12

# 用乘法做转换
cm = inches * 2.54

# 输出结果(自动发现 cm 是浮点数)
print(f"{inches} 英寸 = {cm} 厘米")

# 反过来算:厘米 → 英寸(用除法)
cm_value = 30
inches_value = cm_value / 2.54
print(f"{cm_value} 厘米 = {inches_value:.2f} 英寸")

# 试试取余和整除——12 英寸里有多少个 5 英寸?
count = 12 // 5   # 整除:2 个
remainder = 12 % 5  # 取余:剩下 2 英寸
print(f"12 英寸可以分成 {count} 个 5 英寸,还多 {remainder} 英寸")
▶ 试一试

运行结果:

TEXT 📖 仅展示
12 英寸 = 30.48 厘米
30 厘米 = 11.81 英寸
12 英寸可以分成 2 个 5 英寸,还多 2 英寸


2. 比较运算符

比较运算符用来判断两个值之间的关系,结果永远是一个布尔值TrueFalse)。它们是你写判断逻辑的基础工具。

运算符 名称 示例 结果
== 等于 5 == 3 False
!= 不等于 5 != 3 True
> 大于 5 > 3 True
< 小于 5 < 3 False
>= 大于等于 5 >= 5 True
<= 小于等于 5 <= 3 False
PYTHON
age = 18
print(age == 18)     # True(刚好18岁)
print(age != 18)     # False(并不是"不等于18")
print(age > 21)      # False(还没到美国合法饮酒年龄)
print(age >= 18)     # True(恰好成年,符合大于等于的条件)

(1) 链式比较

Python 支持一种简洁的写法,在其他语言中很少见:

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 不是比较运算符,但它经常和 == 放在一起对比:

PYTHON
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 的别名,指向同一个盒子)

日常开发中,99% 的场景你用 == 就够了。只有判断 None 时,惯例是用 isif result is None:

▶ 示例:判断一个人能不能参加百米赛跑(难度⭐)

比较运算符最常见的用途就是"把某个值和某个标准比一比"。

PYTHON
# 百米赛跑的分组规则
# 年龄 12~15 岁 → 少年组
# 年龄 16~20 岁 → 青年组

participant_age = 14

# 用比较运算符判断属于哪个组
is_teen_group = 12 <= participant_age <= 15    # 链式比较
is_youth_group = participant_age >= 16 and participant_age <= 20

print(f"参赛者年龄:{participant_age}")
print(f"少年组(12~15):{is_teen_group}")
print(f"青年组(16~20):{is_youth_group}")

# == 和 != 的用法
age_verified = True
print(f"年龄已验证:{age_verified == True}")
print(f"年龄未验证:{age_verified != True}")
▶ 试一试

运行结果:

TEXT 📖 仅展示
参赛者年龄: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 取反
PYTHON
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)。

PYTHON
# 对于 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 没被执行

这个特性在实际编程中非常有用:

PYTHON
# 只有用户存在时,才获取他的用户名——避免 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 中很常见,用短路来保证"安全访问"——左边是假值就直接返回,不再执行右边可能出错的代码。

▶ 示例:判断一个数字是否"特殊"(难度⭐⭐)

把比较运算符和逻辑运算符组合起来,判断一个数字是否满足某种"特殊条件"。

PYTHON
# 判断一个数字是不是"特殊数字"
# 定义:在 10~99 之间,并且是 7 的倍数或者包含数字 7

num = 49

# 条件1:在 10~99 之间(链式比较)
in_range = 10 <= num <= 99

# 条件2:是 7 的倍数(取余 + 比较)
multiple_of_7 = num % 7 == 0

# 条件3:包含数字 7(简单判断——十位是7或个位是7)
tens_digit = num // 10    # 提取十位
ones_digit = num % 10     # 提取个位
contains_7 = (tens_digit == 7) or (ones_digit == 7)

# 用逻辑运算符组合所有条件
is_special = in_range and (multiple_of_7 or contains_7)

print(f"数字:{num}")
print(f"在范围内(10~99):{in_range}")
print(f"是7的倍数:{multiple_of_7}")
print(f"包含数字7:{contains_7}")
print(f"是否特殊数字:{is_special}")     # True——49是7的倍数

# 再用短路求值验证——如果第一个条件不满足,后面的根本不会执行
num2 = 200  # 不在范围内
is_special2 = (10 <= num2 <= 99) and (num2 % 7 == 0)
print(f"\n数字 {num2}:第一个条件就是 False,第二个条件不会执行——{is_special2}")
▶ 试一试

运行结果:

TEXT 📖 仅展示
数字:49
在范围内(10~99):True
是7的倍数:True
包含数字7:False
是否特殊数字:True

数字 200:第一个条件就是 False,第二个条件不会执行——False


4. 赋值运算符

除了最基本的 =,Python 还提供了一组"复合赋值运算符",让你能一边运算一边赋值:

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,因为 / 的结果永远是浮点数。如果你确实需要整数结果,用 //= 来避免类型变化。

PYTHON
# 自增在循环中的典型用法
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
PYTHON
# 字符串拼接
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
# 用字符串运算生成一张简单的名片

name = "李明"
title = "Python 工程师"
company = "科技有限公司"

# 用 + 拼接名片内容
card_line1 = "姓名:" + name
card_line2 = "职位:" + title
card_line3 = "公司:" + company

# 用 * 生成分割线
separator = "-" * 25

# 组合成完整名片
business_card = separator + "\n" + card_line1 + "\n" + card_line2 + "\n" + card_line3 + "\n" + separator

print("生成的名片:")
print(business_card)

# 用 in 检查是否包含特定信息
search_term = "Python"
print(f'\n名片中是否包含 "{search_term}":{search_term in business_card}')

# 用 not in 排除某些信息
print(f'名片中不包含 "Manager":{"Manager" not in business_card}')
▶ 试一试

运行结果:

TEXT 📖 仅展示
生成的名片:
-------------------------
姓名:李明
职位:Python 工程师
公司:科技有限公司
-------------------------

名片中是否包含 "Python":True
名片中不包含 "Manager":True


6. 运算符优先级

数学中有"先乘除后加减",Python 也一样——运算符有优先级高低之分。

优先级 类别 运算符 说明
幂运算 ** 右结合(从右往左算)
一元运算符 +x-xnot 正负号、逻辑非
算术运算符 *///% 乘、除、整除、取余
算术运算符 +- 加、减
比较运算符 ==!=><>=<= 比较大小
逻辑运算符 not 逻辑非
逻辑运算符 and 逻辑与
逻辑运算符 or 逻辑或
赋值运算符 =+= 赋值
PYTHON
# 先乘除后加减
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)

▶ 示例:按揭月供计算器(难度⭐⭐)

公式看起来复杂,拆开看无非就是算术运算加上括号控制优先级。

PYTHON
# 计算房贷月供(等额本息)
# 公式:月供 = 贷款总额 × 月利率 × (1 + 月利率)^还款月数 ÷ [(1 + 月利率)^还款月数 - 1]

# 假设贷款 100 万,年利率 4.5%,贷 30 年
loan_amount = 1_000_000    # 贷款总额(用下划线分隔数字,Python 3.6+ 支持,不影响计算)
annual_rate = 0.045        # 年利率
years = 30
months = years * 12        # 还款月数
monthly_rate = annual_rate / 12   # 月利率

# 一步步拆开算——先算最复杂的部分
rate_power = (1 + monthly_rate) ** months         # (1 + 月利率)^还款月数
numerator = loan_amount * monthly_rate * rate_power   # 分子
denominator = rate_power - 1                          # 分母

monthly_payment = numerator / denominator

print(f"贷款金额:{loan_amount:,} 元")
print(f"年利率:{annual_rate * 100}%")
print(f"贷款年限:{years} 年")
print(f"每月还款:{monthly_payment:.2f} 元")
print(f"总还款额:{monthly_payment * months:,.2f} 元")
print(f"利息总额:{monthly_payment * months - loan_amount:,.2f} 元")
▶ 试一试

运行结果:

TEXT 📖 仅展示
贷款金额:1,000,000 元
年利率:4.5%
贷款年限:30 年
每月还款:5,066.85 元
总还款额:1,824,066.95 元
利息总额:824,066.95 元
💡 提示1_000_000 中的下划线只是给人看的,Python 会忽略它。这是 Python 3.6 引入的数字可视化分隔符。优先级记不全没关系,拿不准就加括号——上面的公式加了括号后,任何人都能一眼看懂运算顺序。



7. 浮点数精度问题

这是每个学编程的人都会碰到的坑:

PYTHON
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) 什么时候要注意

PYTHON
# 正确的浮点数比较方式
result = 0.1 + 0.2
epsilon = 1e-10     # 一个非常小的数,相当于 0.0000000001
print(abs(result - 0.3) < epsilon)   # 输出 True
PYTHON
print(f"{0.1 + 0.2:.2f}")   # 输出 0.30
PYTHON
# 一个实际例子:累加 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 提供了几个函数来在不同数字类型之间转换:

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 转成十进制)

▶ 示例:数据类型转换实战(难度⭐)

一个"输入→转换→计算→输出"的完整流程。

PYTHON
# 模拟用户输入(实际用 input(),这里用变量模拟)
user_input = "25"       # 注意:这是字符串,不是数字

# 不转换就做加法会怎样?
# print(user_input + 5)  ← 去掉注释会报错:不能把字符串和数字相加

# 正确做法:先用 int() 转换
age = int(user_input)

# 现在可以正常做算术了
age_next_year = age + 1
print(f"你输入了:{user_input}(类型:{type(user_input)})")
print(f"转换后:{age}(类型:{type(age)})")
print(f"明年你就 {age_next_year} 岁了")

# 反过来:把计算结果转回字符串,准备输出
output_message = "你已经 " + str(age) + " 岁了"
print(output_message)
▶ 试一试

运行结果:

TEXT 📖 仅展示
你输入了:25(类型:<class 'str'>)
转换后:25(类型:<class 'int'>)
明年你就 26 岁了
你已经 25 岁了


9. 常见应用场景


❓ 常见问题

Q:==is 到底有什么区别?什么场景该用哪个? A: == 比较的是值("里面装的东西一样吗"),is 比较的是身份("是同一个对象吗")。比如 a = [1, 2]; b = [1, 2]; c = a,则 a == bTrue(值一样),但 a is bFalse(两个不同的列表对象);a is cTrue(c 只是 a 的别名)。日常开发中,99% 的场景用 == 就够了。判断是否为 None 时,惯例用 isif result is None:

Q:andor 的短路求值在实际中有什么坑? A: 最常见的坑是:user_input = input() or "默认值"——如果 input() 返回空字符串(假值),or 会短路直接取右边的默认值。这个写法很常见,但新手容易误读。另一个陷阱是函数调用放 and 右边——如果左边是假值,右边函数不会执行,你可能意识不到某些操作被跳过了。好习惯是:如果右边的表达式有副作用(比如文件写入、数据库更新),不要依赖短路行为,分开写。

Q:/// 到底什么时候用哪个? A: 如果你需要精确的带小数点的结果(比如 7 ÷ 3 = 2.333...),用 /。如果你只需要整数结果(比如把 7 个苹果分给 3 个人,每人分 2 个,剩下 1 个),用 // 配合 %。如果你是新手且不确定,默认用 /,至少不会丢掉精度。明确需要整数后再改成 //

Q:幂运算符的右结合是什么意思?为什么这样设计? A: 右结合意味着 2 3 2 被解析为 2 (3 2),即先算 3² = 9,再算 2⁹ = 512。如果从左到右算就是 (2³)² = 8² = 64,结果完全不同。这和数学中的习惯一致:a^b^c 的标准解释是从右上角开始算。你可以通过加括号来强制顺序:(2 3) 2 得到 64。


📖 小节


📝 作业

  1. 基础题(难度⭐):定义三个变量 a=10b=3c=20,分别计算并输出:a + b * c(a + b) * ca ** ba // bc % aa > b and c > 15。先猜结果,再运行验证。

  2. 进阶题(难度⭐⭐):给定年份 year = 2026,判断它是不是闰年。闰年规则:能被 4 整除但不能被 100 整除,或者能被 400 整除。提示year % 4 == 0 判断能否被 4 整除。

  3. 挑战题(难度⭐⭐⭐):写一个简单的"温控系统"。给定 current_temp = 38high_alarm = 37low_alarm = 5。如果当前温度超过高温线或低于低温线,触发警报。如果当前温度在警戒线边缘(±2 度以内),触发"注意"而非"警报"。要求只用算术、比较和逻辑运算符实现完整的判断逻辑。提示abs(current_temp - high_alarm) <= 2 判断是否在高温警戒边缘。

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏