# 5f 培训内容：组合数据类型与真题数据结构

## 课程定位

- 对象：已学字符串、条件与循环的 Python 初学者。
- 建议时长：100 分钟；主线是“列表装多条、字典描述一条、嵌套结构还原网页数据”。
- 先修要求：能读懂变量、类型转换、`for`、`if`、函数和字符串格式化。
- 参考教材：`../5f.pdf`，对应《Python 快速编程入门（第 3 版）》第 5 章。
- 真题依据：`../../../python真题/` 中名仕、科图、青娅三套题干与代码。
- 课堂材料：`../第05讲_Python列表、元组、字典与集合.ipynb`、`课堂Slides.tex`、`课堂Slides.pdf`、`课后练习.py`。

课程沟通目标：学生能根据数据关系选择列表、元组、集合或字典；重点掌握真题中的列表收集、列名列表、请求参数字典、嵌套 JSON 取值，以及由组合数据构造 DataFrame。

## Notebook 课堂使用顺序

`第05讲_Python列表、元组、字典与集合.ipynb` 延续前面章节的课堂节奏，每个教学单元均按以下顺序推进：

1. **用法、函数或概念**：明确结构特点和适用场景；
2. **代码讲解**：拆解输入、操作、返回值及是否修改原对象；
3. **课堂演示（样本代码）**：教师先预测，再运行并修改一个样例；
4. **课堂练习（学生填写）**：学生使用不同数据独立补全；
5. **结果核验**：根据预期结构、行数、键和值检查结果。

## 取舍说明

教材第 5 章包含列表、元组、集合、字典、推导式、运算符和多个综合案例。三套真题的直接命中点主要集中在列表与字典：

- 名仕题使用空列表收集每页 DataFrame，并用 `append()` 添加；
- 名仕题循环遍历店铺记录，每条店铺记录是字典；
- 名仕题通过 `response['data']['list']` 访问嵌套 JSON；
- 名仕题动态修改请求参数字典中的 `clvalue` 和 `pageNum`；
- 科图、青娅题使用列名列表选择多列；
- 青娅题使用目标值列表配合 `.isin()`；
- 三套题都使用字典创建 DataFrame、设置请求头或传递聚合规则；
- `pd.read_html()` 返回 DataFrame 列表，需要理解列表与 `extend()`。

因此，本课重点讲列表、字典及其嵌套。元组、集合保留基本识别和实用场景；复杂推导式、通讯录、成语接龙、集合高级方法不作为必做。

## 学习目标与验收

| 目标 | 学生可观察行为 | 验收方式 |
|---|---|---|
| 选择数据结构 | 能说明列表、元组、集合、字典的区别 | 结构选择题 |
| 操作列表 | 会索引、切片、遍历、`append()`、`extend()` | 收集分页结果 |
| 使用列表表达业务规则 | 用列名列表和目标列表控制顺序与筛选 | 科图、青娅微案例 |
| 操作字典 | 会创建、访问、`get()`、添加和修改 | 请求参数练习 |
| 读取嵌套结构 | 能逐层写出 `response['data']['list']` | 名仕 JSON 微案例 |
| 连接 pandas | 能用记录列表或列字典构造 DataFrame | 三种建表方式 |
| 防止常见错误 | 区分 `append`/`extend`、`[]`/`{}`、键/索引 | 诊断题 |

## 100 分钟流程

| 时间 | 教学环节 | 教师动作 | 学生活动 | 形成性评价 |
|---:|---|---|---|---|
| 0-8 分钟 | 真题导入 | 标出三套代码中的中括号和大括号 | 判断列表或字典 | 能否识别结构 |
| 8-18 分钟 | 四类结构 | 对比顺序、可变、唯一、键值关系 | 完成结构选择 | 是否按业务关系选择 |
| 18-31 分钟 | 列表访问 | 演示索引、切片、遍历 | 读取列名和目标值 | 是否理解索引从 0 开始 |
| 31-44 分钟 | 列表收集 | 对比 `append()` 与 `extend()` | 模拟收集分页结果 | 是否理解整体与逐项 |
| 44-54 分钟 | 列表业务角色 | 列名顺序、目标列表、空列表保护 | 编写选择清单 | 是否保持题目顺序 |
| 54-62 分钟 | 元组与集合 | 固定记录、去重和成员判断 | 完成识别练习 | 是否知道集合无序 |
| 62-74 分钟 | 字典基础 | 创建、键访问、`get()`、遍历 | 读取商品记录 | 是否区分键与索引 |
| 74-84 分钟 | 字典修改 | 动态更新 API 请求参数 | 模拟店铺切换 | 页码是否正确重置 |
| 84-93 分钟 | 嵌套 JSON | 画出字典-字典-列表结构 | 逐层取商品记录 | 是否找对对象层级 |
| 93-100 分钟 | DataFrame 与离场检验 | 对比三种建表输入 | 完成最小真题流水线 | 行数、列数、顺序正确 |

## 核心讲解

### 1. 先看业务关系，再选数据结构

- 列表：有顺序、允许重复，适合列名、目标项目、分页结果和多条记录；
- 元组：有顺序但不可变，适合不应修改的固定组合或函数多返回值；
- 集合：元素唯一、无序，适合去重和快速成员判断；
- 字典：键映射到值，适合一条商品记录、请求头、请求参数和 JSON 对象。

### 2. `append()` 与 `extend()` 的差别必须掌握

`append(x)` 把 `x` 作为一个整体放到列表末尾；`extend(iterable)` 把可迭代对象中的元素逐个加入。真题收集一个 DataFrame 时使用 `append()`；合并 `pd.read_html()` 返回的 DataFrame 列表时可使用 `extend()`。

### 3. 列表顺序会进入最终结果

`df[['项目', '2022年度', '2021年度', '2020年度']]` 中的列名列表不仅选择字段，也决定列顺序。不要用集合代替列名列表，因为集合无序且会去重。

### 4. 字典访问要分清“直接取值”和“允许缺省”

`record['销量']` 在键不存在时抛出 `KeyError`，适合必须存在的评分字段；`record.get('退单量', 0)` 可以提供默认值，适合业务上允许缺省的字段。是否使用默认值必须由题目口径决定。

### 5. 字典是可变对象

`goods_req['pageNum'] += 1` 会直接修改原字典。名仕题切换店铺时，应同时更新 `clvalue` 并把 `pageNum` 重置为 1；否则后一家店铺可能从错误页码开始。

### 6. 嵌套 JSON 必须逐层判断类型

```python
response_data['data']['list']
```

先确认 `response_data` 是字典，`response_data['data']` 仍是字典，最后的 `list` 对应记录列表。不要看到 `list` 这个单词就误以为上一层也是列表。

### 7. pandas 常见的三种组合数据输入

```python
pd.DataFrame(list_of_dicts)
pd.DataFrame({'列名': [值]})
pd.concat(dataframe_list, ignore_index=True)
```

记录列表适合网页 JSON；列字典适合人工构造结果；DataFrame 列表适合分页或多个 HTML 表的纵向合并。

## 真题微案例

### 名仕：店铺列表、请求字典与嵌套 JSON

核心链条：遍历店铺记录列表 -> 从店铺字典取名称 -> 修改请求参数字典 -> 从嵌套响应取记录列表 -> 转 DataFrame -> 放入 DataFrame 收集列表 -> 最后统一 `concat()`。

### 科图：HTML 表格列表与列名列表

`pd.read_html()` 返回列表。多个表需要收集后合并；分析时用列名列表确保字段范围和顺序。分组字段 `['年', '区域分布']` 也是列表。

### 青娅：目标列表与列字典建表

`.isin(targets)` 中的 `targets` 是目标项目列表；`pd.DataFrame({'项目': [...], '2020年度': [...]})` 使用字典描述列，字典值必须是等长的一维数据。

## 常见误区与纠偏话术

| 误区 | 纠偏 |
|---|---|
| `append([1, 2])` 会加入两个元素 | `append` 把整个列表作为一个元素加入 |
| `extend('AB')` 会加入字符串 `AB` | 它会逐个加入 `'A'` 和 `'B'` |
| 列表索引从 1 开始 | 第一个元素索引为 0，最后一个可用 -1 |
| `{}` 是空集合 | `{}` 是空字典；空集合必须写 `set()` |
| 集合适合保存列顺序 | 集合无序，不适合控制输出列顺序 |
| 字典通过数字索引取第一个元素 | 字典通过键取值，不按位置访问业务值 |
| `get()` 返回 0 说明原数据就是 0 | 默认值是代码补出的，必须符合业务口径 |
| 修改请求字典不会影响原对象 | 字典可变，赋值会直接更新当前对象 |
| JSON 中的 `list` 键意味着上一层是列表 | 键名不决定容器类型，应逐层检查 `type()` |
| DataFrame 字典中的值可以长短不一 | 各列长度必须一致，否则无法建表 |

## 课后练习使用方式

1. 学生只修改 `课后练习.py` 中的 TODO。
2. 每题先画出数据结构，再写访问路径。
3. 分页微案例必须先收集、后合并，不在循环中反复覆盖最终结果。
4. 完成后确保文件从上到下一次运行不出现异常。

评分建议：结构选择 15%，列表操作 25%，字典操作 25%，嵌套 JSON 20%，DataFrame 连接 10%，解释与代码可读性 5%。
