学径XUEJING · 个人学习平台通知设置

课程库 AI 主线 Python 进阶语法 › 第 2

字典与集合进阶 —— 嵌套结构:JSON 的前置直觉

普通课60 分钟

本课导读

阶段 0 你已经会用字典的增改查和遍历,也见过"列表套字典"。本课把容器功夫再升两级:嵌套结构(字典套字典、套列表——未来你从 API 拿到的数据就长这样)和一位新成员集合(set)——专治重复数据。学完后,看到一份多层嵌套的数据你能一层层拆开取值,这是阶段 3 调用 AI 接口时读懂返回结果的地基。预计 60 分钟。

热身:更体面的取值方式

阶段 0 学过"用 in 探路再取值"防 KeyError。字典还有个更顺手的方法 .get()

Python
  • 字典.get(键, 备用值):键存在返回对应值,不存在不报错,返回备用值
  • 备用值可以省略,省略时查不到返回 None
  • 什么时候用哪个?"查不到也正常,给个兜底"用 .get();"查不到说明数据有问题,就该报错"用 字典[键]——报错有时是好事,它帮你揪出脏数据

字典套字典:数据长出了层次

行政小美管理员工档案。每个员工的信息本身就是一组键值对,于是字典里装字典:

Python

读嵌套取值链的口诀:从左往右,一层剥一个方括号staff["e001"]["name"] 读作"先在 staff 里查 e001,得到一个字典,再在里面查 name"。

提示

类比记忆:嵌套字典是带抽屉的文件柜——外层键是抽屉标签(工号),拉开抽屉,里面是一份贴着字段标签的档案。取"e001 的名字"= 先开 e001 抽屉,再翻 name 那一栏。

混合嵌套:JSON 的形状

字典和列表可以随意互相嵌套。看一份"订单"数据——这就是你未来从 API 拿到的 JSON 长的样子,先混个脸熟:

Python

拆解 order["items"][0]["title"]

  • order["items"] —— 按键取出商品列表
  • [0] —— 列表按下标取出第一个商品(一个字典)
  • ["title"] —— 字典按取出商品名

方括号长得一样,但字典里填键、列表里填下标——看清楚每一层是什么容器,就不会剥错。

说明

为什么说这是 JSON 的前置直觉?JSON 是互联网上传数据的通用格式,而它的结构翻译成 Python 恰好就是"字典 + 列表 + 字符串/数字/True/False"的嵌套。你现在练的每一次剥洋葱,都是在为 U1.3 的 JSON 课和阶段 3 的 API 课攒手感。

集合:自带去重的袋子

运营小林统计活动签到,名单里有人重复签了好几次。集合(set)出场——它只有一个信念:同样的东西只留一份

Python

要点:

  • set(列表) 一步去重;{"a", "b"} 也能直接创建集合(注意:空集合必须写 set(){} 创建的是空字典
  • 集合没有顺序、没有下标——unique[0] 会报错;要顺序就 sorted() 转回列表
  • in 判断是集合的强项,数据量大时比列表快得多

两个名单的对比,是集合的另一绝活:

Python

提示

类比记忆:& 像"要满足"(交),| 像"满足其一"(并),- 像"减去"(差)。"哪些老客户这个月流失了" = 上月名单 - 本月名单,一个减号的事。

容器选型小结

到这里,Python 四大容器你已集齐三个半(元组在 U1.1 函数课顺带见)。选型口诀:

需求选谁理由
一串有顺序的东西列表有下标、能切片、可排序
按名字查属性字典键值对,取值不靠位置
去重 / 快速判断"在不在" / 名单对比集合唯一性 + in 快 + 交并差
多层结构(如 JSON)字典和列表嵌套现实数据的天然形状

✍️ 练习

练习 1:安全查询

.get() 改写:查询"丽丽"和"小雨"的电话,查不到的显示"未登记"。

Python
✅ 参考答案
contact = {"小雨": "138-0000-1111", "阿杰": "139-2222-3333"}

print(contact.get("丽丽", "未登记"))
print(contact.get("小雨", "未登记"))

练习 2:剥洋葱取值

从下面的数据里打印出:① 第二门课的名字 ② 讲师的城市 ③ 第一门课的学员人数。

Python
💡 提示

一层层看容器类型:school 是字典(按键取),courses 是列表(按下标取),列表里的每一项又是字典(按键取)。

✅ 参考答案
school = {
    "teacher": {"name": "老周", "city": "杭州"},
    "courses": [
        {"name": "Python 入门", "students": 45},
        {"name": "数据分析", "students": 32}
    ]
}

print(school["courses"][1]["name"])
print(school["teacher"]["city"])
print(school["courses"][0]["students"])

练习 3:流失客户分析(挑战)

给出上月和本月的下单客户名单(有重复),回答:① 两个月都下单的有谁 ② 上月下单、本月没下单的"流失客户"有谁 ③ 两个月合计有多少不同客户。

Python
💡 提示

set() 去重后:都下单用 &,流失用 -(谁减谁想清楚),合计人数是并集 |len()

✅ 参考答案
last_month = ["老王", "小雨", "阿杰", "小雨", "丽丽"]
this_month = ["阿杰", "小陈", "老王", "阿杰"]

last = set(last_month)
this = set(this_month)

print(f"两个月都下单:{last & this}")
print(f"流失客户:{last - this}")
print(f"合计客户数:{len(last | this)}")

📝 随堂测验

随堂测验0 / 5 题正确

1. d.get("x", 0) 和 d["x"] 在键 "x" 不存在时的区别是?

2. data = {"a": [{"b": 7}]},取出 7 的写法是?

3. set(["A", "B", "A", "C", "B"]) 的元素个数是?

4. 想知道“上月下单但本月没下单”的客户,用哪个集合运算?

5. 关于空容器的创建,正确的是?

本课小结

  • .get(键, 备用值):查不到不报错的温和取值;该报错时仍用方括号
  • 嵌套结构取值:从左往右一层剥一个,字典填键、列表填下标
  • "字典+列表"的嵌套就是 JSON 的形状——API 时代的数据通用语言
  • 集合:set() 一行去重、in 快查、& | - 做名单对比;无顺序无下标

下一课升级函数:默认参数、关键字参数、一次返回多个值——你的函数从"能用"进化到"好用"。

划选正文任意文字可高亮、批注或加入复习卡

讨论

载入中…