# Python 题目知识点梳理

> [!summary]
> 原有内容已按“基础算法”和“办公自动化”重新归类。可直接运行的算法见 [[计算机系/Python/Python常用算法模板.md]]，Word 与邮件示例见 [[计算机系/Python/Python办公自动化示例.md]]。

## 题目与知识点总览

| 题目或示例 | 核心知识点 | 主要易错点 |
| --- | --- | --- |
| 枚举整数的因数对 | `range`、取模、整除、平方根优化 | 重复枚举、浮点平方根边界 |
| 生成等差数列并求和 | 列表推导式、公式计算 | 项数与下标混淆、误用浮点除法 |
| 筛选质数 | 函数、布尔值、提前返回、试除法 | 把 0 或 1 当成质数、漏判平方数 |
| 判断回文数 | 字符串转换、切片 | 负数定义不明确 |
| 生成 Word 文档 | 第三方包、对象方法、表格与图片 | 固定行数、图片路径不存在 |
| 发送邮件 | SMTP、第三方包、环境变量 | 泄露授权码、混淆密码与授权码 |

## 1. 输入、类型转换与格式化输出

`input()` 的返回值始终是字符串。需要进行数值运算时，应显式转换：

```python
n = int(input("请输入整数："))
```

格式化输出可使用 f-string：

```python
print(f"{factor} * {n // factor} = {n}")
```

- `{表达式}` 会在输出前求值。
- `//` 是整除，结果向下取整；`/` 始终得到浮点数。
- `%` 得到余数，`n % factor == 0` 表示 `factor` 能整除 `n`。

## 2. 循环与 `range`

```python
for i in range(start, stop, step):
    ...
```

`range` 使用左闭右开区间，即包含 `start`，不包含 `stop`。

- `range(n)` 产生 `0` 到 `n - 1`；
- `range(1, n + 1)` 产生 `1` 到 `n`；
- `range(3, n + 1, 2)` 只枚举不小于 3 的奇数。

明确区间端点是因数枚举、质数判断等题目的关键。

## 3. 列表与列表推导式

逐步追加：

```python
sequence = []
for i in range(n):
    sequence.append(a + d * i)
```

等价的列表推导式：

```python
sequence = [a + d * i for i in range(n)]
```

列表推导式适合逻辑简单的映射或筛选；如果包含多个分支、副作用或复杂状态，普通循环通常更清楚。

## 4. 函数、布尔值与提前返回

质数判断适合封装成函数：

```python
def is_prime(number: int) -> bool:
    ...
```

- `number: int` 和 `-> bool` 是类型提示，不会自动强制检查类型。
- `True` 和 `False` 是布尔值。
- 一旦找到反例即可立即 `return False`，无需继续循环。
- 将判断逻辑封装为函数后，可以方便地测试和复用。

## 5. 平方根边界与算法优化

### 5.1 因数为什么只需枚举到平方根

若 $a\times b=n$ 且 $a>\sqrt n$、$b>\sqrt n$，则 $ab>n$，产生矛盾。因此每一对因数中至少有一个不超过 $\sqrt n$。

Python 可使用整数平方根：

```python
from math import isqrt

limit = isqrt(n)
```

`isqrt(n)` 精确返回 $\lfloor\sqrt n\rfloor$，避免浮点误差。

### 5.2 质数判断的优化顺序

1. 小于 2 的数不是质数；
2. 2 是质数；
3. 大于 2 的偶数不是质数；
4. 只试除从 3 到 $\sqrt n$ 的奇数；
5. 找到任意因数后立即结束。

单个整数的试除法时间复杂度约为 $O(\sqrt n)$。若要生成很大范围内的全部质数，应进一步学习埃拉托斯特尼筛法。

## 6. 等差数列

首项为 $a$、公差为 $d$、项数为 $n$ 时，第 `i` 项（从 `i = 0` 开始）为：

$$
a_i=a+id
$$

前 $n$ 项和为：

$$
S_n=\frac{n[2a+(n-1)d]}{2}
$$

整数等差数列的和一定是整数，可使用 `// 2`，避免无意义的 `.0`。同时应检查项数是否为非负数。

## 7. 字符串与回文判断

```python
text = str(number)
reversed_text = text[::-1]
```

切片格式为 `sequence[start:stop:step]`。步长为 `-1` 时得到反向序列，因此 `text == text[::-1]` 可判断字符串是否为回文。

对于负整数，字符串中包含负号，例如 `-121` 反转后为 `121-`。题目应先明确负数是否可能被视为回文数。

## 8. 第三方包与模块

原示例使用了两个第三方包：

- `python-docx`：创建和修改 `.docx` 文档，导入名为 `docx`；
- `yagmail`：简化 SMTP 邮件发送。

安装命令：

```powershell
python -m pip install python-docx yagmail
```

第三方包不是 Python 标准库的一部分。分享脚本时，应同时记录依赖名称；正式项目可使用 `requirements.txt` 或 `pyproject.toml` 管理依赖。

## 9. Word 文档生成

`python-docx` 的典型流程为：

1. 创建 `Document`；
2. 添加标题、段落、图片或表格；
3. 根据实际数据长度填充表格；
4. 调用 `save` 写入 `.docx` 文件。

不应把表格行数固定为 `6`，而应使用 `len(records)`。图片路径、输出目录和文件权限都可能导致异常，批量任务中应进行检查或异常处理。

## 10. 邮件发送与凭据安全

SMTP 示例需要区分：

- 发件邮箱地址；
- SMTP 服务器地址；
- 邮箱服务商生成的 SMTP 授权码；
- 收件人、主题和正文。

> [!danger]
> 不要把邮箱密码或 SMTP 授权码直接写进笔记和源代码，也不要提交到 Git。应通过环境变量、系统凭据管理器或专门的密钥服务读取。

发送前还需在邮箱设置中启用 SMTP 服务。不同服务商的服务器、端口和认证规则可能不同，应以服务商当前文档为准。

## 11. 阅读与记笔记约定

- 标题后的 `*` 可用于表示选读或相对困难的内容；
- 首次出现的重要术语可同时记录中英文，如「列表 list」；
- **粗体**用于重点结论，不宜滥用；
- Python 中表示“空值”的对象是 `None`，判断时通常写 `value is None`；
- 示例代码仍应遵守正常缩进与注释规范，避免为了压缩篇幅而降低可读性。

## 12. 高频问题清单

- [ ] 是否记得把 `input()` 的结果转换为需要的类型？
- [ ] `range` 的右端点是否需要加 1？
- [ ] 应该使用 `/` 还是 `//`？
- [ ] 质数判断是否正确处理了 0、1、2 和偶数？
- [ ] 平方根上界是否包含完全平方数的平方根？
- [ ] 函数是否能在找到结论后提前返回？
- [ ] 列表推导式是否仍然清晰易读？
- [ ] 外部文件路径是否存在？
- [ ] 表格大小是否根据数据动态生成？
- [ ] 密码、授权码和个人邮箱是否从代码中移除？

## 13. 建议复习顺序

1. 变量、输入输出和基本运算；
2. 条件判断、循环和 `range`；
3. 字符串、列表与切片；
4. 函数、布尔值和类型提示；
5. 因数、质数等基础算法；
6. 文件路径、异常和模块；
7. 第三方包与办公自动化；
8. 环境变量、依赖管理与凭据安全。
