Python中%运算符求余数的基本用法

Oliver
Oliver
发布时间:2026-10-25| 3人浏览过
原创
在 Python 中,百分号 % 是模运算符(Modulo Operator),专门用于计算两个数相除后的余数。其基本语法为 r = a % b。与部分其他语言不同,Python 采用向下取整(Floor Division)的数学定义,因此余数的正负号始终与除数保持一致。本文将从基本语法、运算原理、负数规则、实战场景及常见陷阱进行系统梳理。

一、% 运算符的基本语法与核心概念

求余数是编程中最常用的算术运算之一。在 Python 中,表达式 a % b 表示计算被除数 a 除以除数 b 后的余数(Remainder)。

最基本的使用场景是两个正整数之间的求模:

# 示例 1:正整数求余
remainder1 = 14 % 4
print("14 % 4 的结果是:", remainder1)

remainder2 = 15 % 5
print("15 % 5 的结果是:", remainder2)

示例输出:

14 % 4 的结果是: 2
15 % 5 的结果是: 0

在上述代码中,14 可以整除 4 得 3,剩余 2,因此 14 % 4 的结果为 2;而 15 能被 5 整除,没有剩余,因此 15 % 5 的结果为 0。当余数为 0 时,即表示两个数能够整除。

Python中%运算符求余数的基本用法
图 1:数轴上的模运算与分组关系

二、Python模运算背后的数学原理与计算步骤

要深入掌握 % 运算符,不能仅靠除法经验,必须理解 Python 内部的数学定义。在 Python 中,模运算严格遵循以下数学恒等式:

r = a - (a // b) * b

其中,// 表示向下取整除法(Floor Division),即商 q = floor(a / b),它总是取不大于实际商的最大整数(向负无穷方向取整)。由此可以推导出余数 r 的四步计算过程:

  1. 步骤一(浮点商):计算实数除法商 a / b。
  2. 步骤二(向下取整):通过 q = a // b 获取向负无穷取整后的整数商。
  3. 步骤三(基准乘积):计算该商所对应的整除基准值 base = q * b。
  4. 步骤四(求差得余):由 r = a - base 得到最终余数。
Python中%运算符求余数的基本用法
图 2:Python 模运算四步执行推导图

三、负数参与取模的规则与语言对比

许多从 C、C++、Java 等语言转向 Python 的开发者常对负数取模的结果感到意外。例如在 C/Java 中 -7 % 3 的结果是 -1,而在 Python 中 -7 % 3 的结果却是 2。

原因在于取整策略的不同:

  • 向零截断(Truncation toward zero):C/Java 中整数除法直接舍弃小数部分,-7 / 3 = -2.33 被截断为 -2,因此余数为 -7 - (-2 * 3) = -1。余数符号与被除数一致。
  • 向下取整(Floor toward -infinity):Python 的 // 向下舍入,-7 // 3 为 -3,因此余数为 -7 - (-3 * 3) = 2。余数符号与除数一致。
核心法则

在 Python 中,模运算余数 r 的正负符号永远与除数 b 的符号保持一致(或者为 0)。
若除数 b > 0,则余数范围为 [0, b);
若除数 b < 0,则余数范围为 (b, 0]。

下面通过完整的四种符号组合代码验证这一规则:

# 四种正负号组合测试
print("正数 % 正数 ( 7 %  3):",  7 %  3)
print("负数 % 正数 (-7 %  3):", -7 %  3)
print("正数 % 负数 ( 7 % -3):",  7 % -3)
print("负数 % 负数 (-7 % -3):", -7 % -3)

示例输出:

正数 % 正数 ( 7 %  3): 1
负数 % 正数 (-7 %  3): 2
正数 % 负数 ( 7 % -3): -2
负数 % 负数 (-7 % -3): -1
Python中%运算符求余数的基本用法
图 3:正负数求模计算过程与符号定律对照

四、% 运算符的典型应用场景

在实际工程和算法开发中,% 运算符常用于以下四类常见场景:

1. 判断数值的奇偶性与整除

任何整数对 2 求余,余数仅有两种可能:0(偶数)或 1(奇数)。同理,若 x % n == 0,则表明 x 是 n 的整数倍。

def check_parity(number):
    if number % 2 == 0:
        return f"{number} 是偶数"
    else:
        return f"{number} 是奇数"

print(check_parity(18))
print(check_parity(27))

示例输出:

18 是偶数
27 是奇数

2. 环形轮询与周期性循环(循环数组)

在处理轮播图、任务分发轮询或循环队列时,索引不断递增可能超出列表长度。使用模运算可以将任意增长的索引安全映射在 [0, len - 1] 区间内:

servers = ["Server-A", "Server-B", "Server-C"]
num_servers = len(servers)

# 模拟连续发来的 7 个请求
for request_id in range(7):
    assigned_server = servers[request_id % num_servers]
    print(f"请求 {request_id} 分配给: {assigned_server}")

示例输出:

请求 0 分配给: Server-A
请求 1 分配给: Server-B
请求 2 分配给: Server-C
请求 3 分配给: Server-A
请求 4 分配给: Server-B
请求 5 分配给: Server-C
请求 6 分配给: Server-A

3. 时间与度量衡单位转换

当获取到一个总秒数时,通过整除 // 与求余 % 的配合,可以轻松拆分出小时、分钟与秒:

total_seconds = 3675

hours = total_seconds // 3600
remaining_seconds = total_seconds % 3600

minutes = remaining_seconds // 60
seconds = remaining_seconds % 60

print(f"{total_seconds} 秒转换为: {hours} 小时 {minutes} 分 {seconds} 秒")

示例输出:

3675 秒转换为: 1 小时 1 分 15 秒

4. 数据分页与批次处理

当批量导入大量数据时,可以利用模运算在达到批次上限时触发提交动作:

records = list(range(1, 11))
batch_size = 4

for idx, record in enumerate(records, start=1):
    # 处理数据项
    if idx % batch_size == 0 or idx == len(records):
        print(f"记录序号 {idx:2d}:已达到批次上限或到达末尾,触发批量保存")

示例输出:

记录序号  4:已达到批次上限或到达末尾,触发批量保存
记录序号  8:已达到批次上限或到达末尾,触发批量保存
记录序号 10:已达到批次上限或到达末尾,触发批量保存

五、进阶对比、相关函数与避坑指南

在实际使用 % 时,还需要注意与 Python 内置的其它数学函数的搭配使用以及几个易出错的边界情况:

1. 同时获取商和余数:divmod() 函数

如果业务逻辑中既需要整数商,又需要余数,分别调用 // 和 % 会执行两次除法运算。Python 提供了内置函数 divmod(a, b),它在底层一次性返回元组 (a // b, a % b),执行效率更高且代码更简洁:

quotient, remainder = divmod(14, 4)
print(f"商: {quotient}, 余数: {remainder}")

示例输出:

商: 3, 余数: 2

2. 浮点数求模与 math.fmod() 的差异

Python 允许使用 % 对浮点数求模,例如 5.5 % 2 得到 1.5。但由于 IEEE 754 二进制浮点数的精度限制,某些计算可能出现微小的精度偏差(例如 7.3 % 2.1 可能会输出 0.9999999999999998)。

此外,Python 标准库的 math.fmod(x, y) 遵循 C 语言标准平台实现,其余数的符号与被除数一致,与内置 % 运算符截然不同:

import math

# 对比 % 运算符与 math.fmod() 在处理负数时的差异
print("Python 内置 % 运算符: -7.0 % 3.0 =", -7.0 % 3.0)
print("math.fmod() 函数:     math.fmod(-7.0, 3.0) =", math.fmod(-7.0, 3.0))

示例输出:

Python 内置 % 运算符: -7.0 % 3.0 = 2.0
math.fmod() 函数:     math.fmod(-7.0, 3.0) = -1.0

3. 注意事项与异常防护

  • 除数不能为零:与普通除法一样,若 b == 0,执行 a % 0 会抛出 ZeroDivisionError: integer division or modulo by zero,必须在计算前做好除数有效性校验。
  • 运算符优先级:% 与 *、/、// 具有相同的算术优先级,高于加法 + 和减法 -。在复杂表达式中建议使用括号显式注明运算顺序。
Python中%运算符求余数的基本用法
图 4:Python 取模知识结构与避坑指南速查图
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。