WEEK 03 / 16 语言核心 · 类型与数据结构
PYTHON 程序设计 · V2 · 第 3 周(100 分钟 · L6–L7)

看数据先看类型
四种结构怎么选

从今天起,语法课的方法论:每课建立思维模型,不逐个背方法——方法查询交给 AI 和文档。 本周用大模型 API 返回的真实数据当教材,学类型系统与数据结构选型。

所属模块 M2 语言核心← → 翻页 · F 全屏

今日课表(100 分钟)

时间环节要点
0–8导入一段真实 API 返回贴屏幕:730 是什么类型?null 在 Python 里叫什么?
8–20五种核心类型int/float/str/bool/None——从 API 响应里逐个现场取值演示
20–30转换与 f-string「730」+1 报错陷阱;{cost:.4f} 格式化;type() 随时查
30–42动手练习运行场:解析 API 返回 JSON,逐层取值 + 类型判断
42–55四种结构一句话排队/通讯录/塑封文件/筛子——选型口诀:看操作选结构
55–68演示多轮对话 messages 管理 + 字典统计 token 消耗 + 推导式一行提取
68–80动手练习运行场:遍历统计 + 推导式提取 + max 找最长消息
80–90选型辩论去重用 list 还是 set?对话历史用 list 还是 dict?——举手说理由
90–1003D 演示 + 小测一切皆对象内存空间演示(three.js);随堂小测 3 题

运行场练习当堂完成;3D 演示可让学生自己在手机上打开操作。

从一段 API 返回说起

{
  "id": "chatcmpl-001",          # 字符串 str
  "created": 1712345678,          # 整数 int
  "temperature": 0.7,             # 浮点数 float
  "stream": false,               # 布尔 bool(JSON 的 false)
  "object": null,                # None(JSON 的 null)
  "choices": [ {...}, {...} ]     # 列表 list,里面套字典 dict
}

类型转换与 f-string

tokens = 730                          # int
cost = 730 * 0.001 / 1000       # 自动变 float

# 字符串数字陷阱:
"730" + 1        # TypeError!字符串不能加数字
int("730") + 1  # 731 —— 先转换,再运算

# f-string:把变量嵌进字符串
print(f"本次对话 token 数 {tokens},费用 {cost:.4f} 元")

四种数据结构:一句话定位

排队的人list · 有序可变 按位置存取、会增会删。聊天记录、消息列表。 msgs.append(m)
通讯录dict · 键值映射 用名字找内容,查找近 O(1)。API 返回的 JSON 本体、配置。 cfg["model"]
塑封文件tuple · 不可变 定下来就不变:坐标、函数多返回值。 x, y = pos
筛子set · 唯一无序 自动去重、快速判存在。URL 去重。 seen.add(url)

选型口诀:看到数据先问「要什么操作」——按序存取用 list,按键查找用 dict,不许改用 tuple,要去重用 set。

一切皆对象

在 Python 里,数据和行为是绑在一起的:

name = "hello"
type(name)          # <class 'str'> —— 它是 str 类的一个对象
name.upper()       # 'HELLO'    —— upper 是对象自带的方法
name[0]            # 'h'        —— 按索引取字符
name[1:4]         # 'ell'      —— 切片 [起:止)
  • 字符串不可变:所有「修改」操作都是返回新字符串,原串不变
  • 对象有身份(id)与值:== 比较值,is 比较身份——判断 None 一律用 is

3D 直觉演示:一切皆对象 · 内存空间(逐行执行看对象诞生与名字绑定)

3D 演示:一切皆对象 · 内存空间

可交互演示 · 页内直接操作

逐行执行代码,在 3D 内存空间里看对象诞生、名字绑定、a is b 与 a == b 的区别——可拖拽旋转、点击对象查信息卡。 新窗口打开 →

动手:消息列表的统计与提取

交互 · 浏览器内运行(L7 课堂主线)

API 返回的是「列表套字典」——遍历、统计、提取:

推导式:边遍历边加工

# 普通写法
questions = []
for m in messages:
    if m["role"] == "user":
        questions.append(m["content"])

# 推导式:一行等价
questions = [m["content"] for m in messages if m["role"] == "user"]
#            ↑拿什么          ↑从哪遍历            ↑只要谁
  • 读法:对每个 m(来自 messages),如果满足条件,就取 m 的 content
  • AI 生成的代码里到处是推导式——必须能读懂,写不熟练没关系

Manim 风格演示:Base64 编码原理

可交互演示 · 页内直接操作

字节 → 比特流 → 6 位重排 → 查表的每一步动画,支持自定义输入实时重算——经典作业的算法本质,先混个眼熟。 新窗口打开 →

课堂讨论:结构选型辩论

辩题一:去重一批 URL,用 list 还是 set? list 也能去重(逐个判断 in),但每次判断都要从头扫一遍 O(n);set 天然去重、判断近 O(1)——爬虫的 seen = set() 是标准姿势。
辩题二:多轮对话历史,用 list 还是 dict? 对话是「按时间顺序追加」的 → list 套字典(messages 列表);要「按会话 ID 找历史」才在外面再套一层 dict。

举手表决定立场,说出理由——选型理由比结论更重要。

随堂小测(3 题)

交互 · 点击选项作答

课后与下周预告

本周课后
  • 练习:把课堂运行场的「找最长消息」补完
下周:W4 控制流与函数 按条件筛选数据(分支循环)→ 给逻辑起名字(函数与函数契约)。 提前看下周课件 →

深入阅读:M2 模块页 · 经典笔记 4.5 列表 · 6.4 字典