飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 第1章 Python简介

    • Python是什么
    • 安装与运行
    • 交互式解释器
    • 注释与编码规范
  • 第2章 变量与数据类型

    • 变量与对象
    • 整数 int
    • 浮点数 float
    • 复数 complex
    • 布尔值 bool
    • 字符串 str
    • 空值 None
    • 类型转换
  • 第3章 运算符与表达式

    • 算术运算符
    • 比较运算符
    • 赋值运算符
    • 逻辑运算符
    • 位运算符
    • 身份与成员运算符
    • 海象运算符
    • 运算符优先级
  • 第4章 流程控制

    • if 语句
    • if-else 语句
    • if-elif-else 语句
    • match-case 语句
    • 条件表达式(三元运算符)
    • while 循环
    • for 循环
    • range 函数
    • break 与 continue
    • 循环的 else 子句
    • pass 语句
  • 第5章 数据结构

    • 列表创建与索引
    • 列表方法
    • 列表推导式
    • 元组
    • 序列解包
    • 集合
    • 字典创建与访问
    • 字典方法
    • 字典推导式
    • range 对象
  • 第6章 函数

    • 定义函数
    • 位置参数与关键字参数
    • 默认参数
    • 可变参数
    • 解包实参
    • 函数返回值
    • lambda 表达式
    • 文档字符串与注解
    • 作用域与命名空间
    • global 与 nonlocal
  • 第7章 模块与包

    • 模块导入
    • 模块搜索路径
    • 包与相对导入
    • 标准库概览
  • 第8章 文件与输入输出

    • 文件读写
    • 上下文管理器
    • 字符串格式化
    • JSON 与 CSV
  • 第9章 面向对象

    • 类与对象
    • 方法
    • 实例变量与类变量
    • 私有变量
    • 继承
    • 多重继承
    • 魔术方法
    • 属性装饰器
    • 数据类 dataclass
  • 第10章 异常处理

    • 语法错误与异常
    • try-except
    • 异常链与 raise
    • 清理操作
    • 自定义异常
  • 第11章 迭代器与生成器

    • 迭代器协议
    • 生成器
    • 生成器表达式
    • 迭代工具
  • 第12章 高级特性

    • 装饰器
    • 函数式编程
  • 第13章 工程实践

    • 测试与调试
    • 代码质量
    • 虚拟环境

算术运算符

Python 的算术运算符构成了数值计算的基础。+、-、*、/、//、%、** 七个符号覆盖了从基础加减到幂运算的完整需求,但每个运算符在 Python 中的行为都有值得深究的细节。

加减乘除

+ 和 - 既可以做二元运算,也可以做一元运算。一元正号 +x 很少单独使用,但在需要强调数值类型或与其他语言保持一致时会出现;一元负号 -x 则频繁用于表示相反数。

>>> +5
5
>>> -(-3)
3
>>> 50 - 5 * 6
20

乘法 * 在 Python 中不限于数字,还能用于序列重复,如 'un' * 3 得到 'ununun'。但这里聚焦数值运算:当两个操作数都是整数时,结果仍是整数;任一操作数为浮点数时,结果提升为浮点数。

>>> 4 * 3.75 - 1
14.0

除法 / 是 Python 中行为最特殊的算术运算符:无论是否能整除,结果永远是浮点数。这与 C、Java 等语言的整数除法截然不同。

>>> 8 / 5
1.6
>>> 4 / 2
2.0        # 注意不是 2
>>> type(4 / 2)
<class 'float'>

如果需要整数结果,应当使用地板除 //。

地板除 //

// 执行地板除(floor division),即向负无穷方向取整后返回整数(如果操作数都是整数)或浮点数(如果任一操作数为浮点数)。

>>> 17 // 3
5          # 17 / 3 = 5.666...,向下取整为 5
>>> 17.0 // 3
5.0        # 浮点数参与,结果也是浮点数
>>> -17 // 3
-6         # 向负无穷取整,不是向零取整!
>>> 17 // -3
-6

负数地板除是常见的陷阱点。-17 // 3 的结果是 -6 而非 -5,因为 -5.666... 向负无穷方向取整得到 -6。这与 C 语言的整数除法(向零截断)完全不同。

地板除与取模运算存在恒等关系:对于任意数 a 和正数 b,a == b * (a // b) + a % b 始终成立。

>>> 17 // 3
5
>>> 17 % 3
2
>>> 3 * 5 + 2
17

取模运算 %

% 返回除法的余数。当两个操作数都是正数时,行为直观;涉及负数时,结果符号与除数(第二个操作数)一致。

>>> 17 % 3
2
>>> -17 % 3
1          # 余数符号与除数 3 相同,为正
>>> 17 % -3
-1         # 余数符号与除数 -3 相同,为负
>>> -17 % -3
-2

理解负数取模的关键是结合地板除:-17 // 3 得 -6,于是 -17 % 3 必须满足 3 * (-6) + r = -17,解得 r = 1。这种定义保证了上述恒等式在负数场景下依然成立。

取模运算在编程中有大量实用场景:

# 判断奇偶
>>> 7 % 2
1          # 奇数
>>> 8 % 2
0          # 偶数

# 循环索引(防止越界)
>>> index = 10
>>> length = 3
>>> index % length
1          # 等效于第 1 个位置

# 时间换算
>>> seconds = 3661
>>> minutes, remainder = divmod(seconds, 60)
>>> hours, minutes = divmod(minutes, 60)
>>> hours, minutes, remainder
(1, 1, 1)  # 3661 秒 = 1 小时 1 分 1 秒

divmod(a, b) 函数同时返回 (a // b, a % b),比分别计算更高效。

幂运算 **

** 计算乘方,支持整数和浮点数,也支持负指数和分数指数。

>>> 5 ** 2
25
>>> 2 ** 7
128
>>> 2 ** -3
0.125      # 负指数等于倒数
>>> 9 ** 0.5
3.0        # 0.5 次方即开平方
>>> 8 ** (1/3)
2.0        # 1/3 次方即开立方

幂运算的优先级高于一元负号,这是 Python 中最容易踩坑的优先级规则之一:

>>> -3 ** 2
-9         # 解释为 -(3**2),不是 (-3)**2
>>> (-3) ** 2
9          # 加括号才能先算 -3

** 是右结合的,这意味着连续幂运算从右向左计算:

>>> 2 ** 3 ** 2
512        # 2 ** (3 ** 2) = 2 ** 9,不是 (2 ** 3) ** 2 = 64

大指数运算时,Python 的整数可以自动扩展精度,不会溢出:

>>> 2 ** 1000
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376

混合类型运算与类型转换

当整数和浮点数混合运算时,Python 会将整数隐式转换为浮点数再计算,结果类型为浮点数。这种转换是安全的,但在需要精确计算的场景(如财务)中应使用 decimal.Decimal 而非浮点数。

>>> 3 + 2.5
5.5
>>> 10 / 4 * 2
5.0        # 10/4 得 2.5,再乘 2 得 5.0

边界与错误

除零会触发 ZeroDivisionError,无论哪种除法:

>>> 5 / 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

>>> 5 // 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

>>> 5 % 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer modulo by zero

浮点数精度问题也影响算术运算:

>>> 0.1 + 0.2
0.30000000000000004
>>> (0.1 + 0.2) == 0.3
False

对于需要精确表示的十进制数,应使用 decimal 模块:

>>> from decimal import Decimal
>>> Decimal('0.1') + Decimal('0.2')
Decimal('0.3')

交互模式的特殊变量 _

在交互式解释器中,最后一个表达式的结果会自动赋给变量 _。这个变量是只读的,显式赋值会覆盖其特殊行为。

>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
12.5625
>>> price + _
113.0625
>>> round(_, 2)
113.06

算术运算符看似简单,但地板除的取整方向、负数取模的符号规则、幂运算的优先级陷阱,都是实际编码中频繁出错的细节。理解这些行为背后的数学定义,才能写出可靠的数值计算代码。

下一页
比较运算符