昨天学的列表,存"一串同类型的东西"很顺手,但它有个短板:找数据只能靠"第几个"。比如
["小明", 18, "北京"],你要拿年龄,得先记住"年龄在第 1 个位置"。万一中间加了一项,全乱套。真实世界的数据几乎都有名字:人有姓名、年龄、城市,商品有名字和价格,网站要存几百万用户的资料。存这种"有名字的数据",Python 给了专门的容器——字典。它就像一本通讯录:要找小明的电话,直接翻到"小明"那一页就行,不用从头数到第几个。
今天学完,你就能写出"成绩单"这类小程序:用字典存同学成绩,遍历打印"谁:多少分"。
字典长什么样:花括号里的键值对
字典用花括号 {} 包起来,里面是"键:值"的配对,用逗号隔开。键(key)是"名字",值(value)是"内容",一个键对应一个值,就像电话簿里一个名字对应一个号码:
student = {"name": "小明", "age": 18, "score": 92}
# 键(key) 值(value)
# name → 小明
# age → 18
# score → 92
怎么读它?用键取值,就像翻通讯录:
student = {"name": "小明", "age": 18, "score": 92}
print(student) # {'name': '小明', 'age': 18, 'score': 92}
print(student["name"]) # 小明(用键取值,就像翻通讯录)
print(len(student)) # 3(有几个键值对)
empty = {} # 空字典,以后往里加
输出:
{'name': '小明', 'age': 18, 'score': 92}
小明
3
一句话记住结构:{"名字": 内容},左边是键(怎么称呼它),右边是值(它到底是什么)。键一般是字符串,值可以是任何类型。
几个容易写错的地方:字典用花括号 {},别和列表的方括号 [] 混了;键和值之间用冒号 :,键值对之间用逗号 ,——位置写错直接 SyntaxError;字典里的键不能重复,后写的会覆盖先写的(同一个名字只能有一页电话)。
查:从字典里取值
取字典里的值有两种写法,差别在于"键不存在时怎么办":
| 写法 | 键存在时 | 键不存在时 |
|---|---|---|
字典["键"] |
返回值 | 报错 KeyError |
字典.get("键") |
返回值 | 返回 None,不报错 |
日常开发推荐用 get():拿不到数据也不至于让程序崩溃,这是今天最重要的一个点。看代码:
student = {"name": "小明", "age": 18}
print(student["name"]) # 小明(键存在,正常取)
# print(student["city"]) # 报错!KeyError: 'city'(键不存在)
print(student.get("name")) # 小明
print(student.get("city")) # None(不报错,返回"空")
print(student.get("city", "未知")) # 未知(找不到时给个默认值)
get 的第二个参数就是兜底:键找不到时,返回你给的那个默认值:
student = {"name": "小明"}
name = student.get("name", "无名氏")
city = student.get("city", "未知城市") # 没有 city 这个键
print(f"姓名:{name},城市:{city}")
输出:
姓名:小明,城市:未知城市
查之前想先确认键在不在,用 in——注意它判断的是键,不是值:
student = {"name": "小明", "age": 18}
if "name" in student: # 判断的是"键"在不在,不是值!
print("有 name 这个键")
if "city" not in student:
print("没有 city 这个键")
输出:
有 name 这个键
没有 city 这个键
三个点说清楚:in 判断的是键在不在——"小明" in student 是 False,因为小明是值不是键;get() 找不到返回 None,None 打印出来就是这个单词,别把它当成报错;真需要"键不存在就报错让程序停"的场合很少,所以默认记 get 就行。
增和改:其实是同一个动作
往字典里加键、改值,用的是同一个动作:直接给键赋值。键不存在就是"新增",键已存在就是"修改",Python 自动判断,你什么都不用管:
student = {"name": "小明", "age": 18}
student["city"] = "北京" # 没有 city 这个键 → 新增
print(student) # {'name': '小明', 'age': 18, 'city': '北京'}
student["age"] = 19 # 有 age 这个键 → 修改
print(student) # {'name': '小明', 'age': 19, 'city': '北京'}
"新增"和"修改"的写法完全一样,判断标准只有一条:这个键之前存不存在。想一次加多个键值对,用 update():
student = {"name": "小明"}
student["age"] = 18 # 新增 age
student.update({"score": 92, "city": "北京"}) # 一次新增多个键
print(student)
student["age"] = 19 # 修改 age
print(student["age"]) # 19
输出:
{'name': '小明', 'age': 18, 'score': 92, 'city': '北京'}
19
别把增改想复杂了,它就是普通赋值:student["age"] = 19,没有别的魔法。
删:从字典里移除键
删键值对最常用 pop(键),它会把"键和值一起拿走",和列表的 pop() 有点像,但这里传的是键:
| 方法 | 作用 | 例子 |
|---|---|---|
pop("键") |
删掉这个键,并返回它的值 | student.pop("score") |
del 字典["键"] |
删掉这个键(不返回值) | del student["score"] |
student = {"name": "小明", "age": 18, "score": 92}
score = student.pop("score") # 删掉 score 键,值 92 被接住
print(score) # 92
print(student) # {'name': '小明', 'age': 18}
del student["age"] # 删掉 age 键
print(student) # {'name': '小明'}
删不存在的键会报 KeyError,所以稳妥的做法是先判断再删:
student = {"name": "小明"}
if "score" in student: # 有才删,没有就算了
student.pop("score")
else:
print("没有 score 这个键,不用删")
输出:
没有 score 这个键,不用删
三点记牢:pop 的参数是键不是值——student.pop("小明") 会报 KeyError(小明是值);删不存在的键,pop 和 del 都会报错,先 in 判断最稳;想清空整个字典用 student.clear(),得到一个空字典 {}。
遍历:把字典从头到尾过一遍
遍历列表是"每个元素来一遍",遍历字典是"每个键值对来一遍"。有三种方式,最常用的是 items()——一次拿到"键和值"两个东西:
student = {"name": "小明", "age": 18, "score": 92}
# 方式一:只拿键
for key in student:
print(key) # name / age / score
# 方式二:键 + 值(用键去字典里取)
for key in student:
print(key, student[key]) # name 小明 / age 18 / score 92
# 方式三:最常用,用 items 一次拿两个
for key, value in student.items():
print(f"{key}: {value}")
第三种方式最省事,写成绩单就用它:
scores = {"小明": 92, "小红": 85, "小刚": 78}
for name, score in scores.items():
print(f"{name}:{score} 分")
输出:
小明:92 分
小红:85 分
小刚:78 分
有时候只想拿键或只想拿值,用 keys() 和 values():
scores = {"小明": 92, "小红": 85, "小刚": 78}
print(scores.keys()) # dict_keys(['小明', '小红', '小刚'])
print(scores.values()) # dict_values([92, 85, 78])
# 实际使用:把值取出来算平均分
all_scores = list(scores.values()) # 转成列表 [92, 85, 78]
print(sum(all_scores) / len(all_scores)) # 85.0
输出:
dict_keys(['小明', '小红', '小刚'])
dict_values([92, 85, 78])
85.0
三个坑提前讲:for key in student: 只拿到键,要值得写 student[key],想一步到位就用 items();items() 拿出来的循环变量是两个——for key, value in ...,漏一个会报 ValueError: not enough values to unpack;keys() / values() 返回的不是列表(是视图),要用 list() 包一下才能当列表用。
列表还是字典:什么时候用哪个
这是今天最重要的一道判断题。记一句话:存"一串同类型的东西"用列表,存"一个东西的多个属性"用字典。
| 场景 | 用什么 | 例子 |
|---|---|---|
| 一串成绩 / 名单 / 商品名 | 列表 | [92, 85, 78] |
| 一个人的信息(姓名+年龄+电话) | 字典 | {"name": "小明", "age": 18} |
| 全班同学的信息(一串人,每人多个属性) | 列表套字典 | [{"name": "小明", "score": 92}, ...] |
第三行是重中之重:列表 + 字典组合(一个字典列表)几乎能表示所有业务数据,明天的课专门讲它,今天先记住结论:
# 什么时候用列表:一串同类型的
scores = [92, 85, 78] # 一串分数,没有名字
# 什么时候用字典:一个东西的多个属性
student = {"name": "小明", "age": 18, "city": "北京"} # 一个人的名片
# 怎么选:先问自己"数据有没有名字"——有名字用字典,没名字用列表
选择的标准其实就一句话:别拿"第几个"的习惯硬套字典——字典没有"第 0 个",只有"哪个键";反过来,成绩单如果不要名字、只要一串数,那列表就够了。先想清楚数据结构,再写代码。这两个容器都是本周必会,判断标准要能背出来,周测会考。
随堂练习
练习一:我的名片
建一个字典存你自己的信息(姓名、年龄、城市),用 get 取年龄打印,再新增一个"爱好"键,最后遍历打印全部键值对。
提示:me = {} 空字典开始;新增直接 me["爱好"] = "...";遍历用 for k, v in me.items():。
练习二(必做):成绩单
用字典存 3 个同学的成绩({"小明": 92, "小红": 85, "小刚": 78}),用 for 遍历打印"谁:多少分",再用 values() 算出平均分。
提示:平均分 = sum(字典.values()) / len(字典)。
练习三:判断键
用 in 判断"小丽"在不在成绩单里,不在就提醒"还没有小丽的成绩"。
进阶题(可选):带列表属性的字典
给字典加一个列表属性:{"name": "小明", "hobbies": ["篮球", "吉他"]},用 for 循环遍历打印出所有爱好(外层遍历字典拿到 hobbies,内层遍历 hobbies 列表)。
写不出来时,让 AI 搭把手
场景:成绩单小程序写不出来,需要 AI 给参考代码
提示词:
我是 Python 初学者,今天学字典。请帮我写一个成绩单小程序:
用字典存 3 个同学的成绩,遍历打印"谁:多少分",
再算出平均分。用 for k, v in 字典.items() 的方式遍历,代码加注释。
场景:不确定某个数据该用列表还是字典,请 AI 帮忙判断
提示词:
我在学 Python 数据结构,想存这样的数据:多个学生的姓名和成绩。
我应该用列表、字典,还是列表套字典?请用大白话解释三种方案的区别,
并各给一行代码示例。我是初学者,不要讲专业术语。
常见报错速查
| 报错信息 | 什么意思 | 怎么办 |
|---|---|---|
KeyError: 'xxx' |
字典里没有这个键 | 改用 get() 取值,或先用 in 判断再取 |
ValueError: not enough values to unpack |
items() 遍历时循环变量写少了 |
写两个:for key, value in 字典.items(): |
TypeError: unhashable type: 'list' |
拿列表当键了 | 键只能是字符串/数字这类"简单值",值可以是列表 |
打印 None |
get 找不到键返回了空值 |
不是报错,想给个兜底值就在 get 加第二参数 |
收个尾
今天的新概念就一个:字典是"键 → 值"的对应关系,靠名字(键)找数据,不靠下标。取值默认 get("键", 默认值);增改是同一个动作 字典["键"] = 值;删用 pop("键");遍历最常用 for key, value in 字典.items():。最后那句选择标准,今天先背下来:存"一个东西的多个属性"用字典。
明天学集合和组合结构。先学集合——自动去重的"麻袋",给列表洗一遍就剩不重复的;再学本周最重要的组合——列表套字典,一个字典列表就是一张数据表格,以后所有项目的数据都长这样。