1. 什么是字典(dict)?
在 Python 中,字典(dict) 是一种用来存放“键—值对(key–value)”的数据结构。
- 列表:是“按顺序排好的一排格子”(每个格子有索引 0、1、2…)
- 字典:更像是“一个小型的电话簿 / 配置表”,通过键(key)来查对应的值(value)
简单理解:
- 键(key):像“名字”“字段名”“编号”,用来定位
- 值(value):这个键对应的内容
1.1 字典的基本写法
- 用 花括号
{}表示字典 - 每一组“键—值”用 冒号
:连接:键: 值 - 多组之间用 逗号
,分隔
person = {
"name": "小明",
"age": 18,
"city": "北京",
}
print(person)
# {'name': '小明', 'age': 18, 'city': '北京'}
上面这个字典里有 3 个键:
"name"→"小明""age"→18"city"→"北京"
注意:
- 键通常用字符串,比如
"name"、"age",更直观。 - 值可以是任意类型:数字、字符串、列表、字典、布尔值、None 等。
2. 键(key)与值(value)的规则
2.1 键的要求
在 Python 中:
- 键必须是不可变类型,常见的有:
- 字符串:
"name" - 数字:
1、2 - 元组(里面也必须全是不可变的东西)
- 字符串:
- 不能用列表、字典等可变类型当键,否则会报错:
# 正确:字符串当键
data = {"a": 1, "b": 2}
# 正确:数字当键
data2 = {1: "一", 2: "二"}
# 错误:列表当键(会报 TypeError)
# bad = {["a", "b"]: 123}
新手阶段,你可以直接记住:
字典的键一般用字符串,就像字段名。
2.2 值的类型
值几乎可以是任何东西:
student = {
"name": "小红", # 字符串
"age": 20, # 整数
"height": 1.65, # 浮点数
"is_graduated": False,# 布尔值
"hobbies": ["唱歌", "画画"], # 列表
"scores": { # 字典中嵌套字典
"math": 95,
"english": 88,
},
}
3. 创建字典的几种方式
3.1 直接用大括号字面量(最常用)
person = {
"name": "小明",
"age": 18,
}
3.2 用 dict() 函数创建
person = dict(name="小明", age=18)
print(person) # {'name': '小明', 'age': 18}
注意:
- 这种方式里,键必须是有效的变量名(不能有空格、不能以数字开头等),并且会自动当作字符串。
- 大多数时候,还是推荐用
{},更直观。
3.3 先创建一个空字典
有时你暂时还不知道要放哪些键,只是先准备一个“空壳”,后面再逐步往里加键—值。
方法 1:用 {}
person = {} # 空字典
print(person) # {}
方法 2:用 dict()
person = dict()
print(person) # {}
新手建议:
推荐用
{}来创建空字典,简单清楚。
4. 访问字典中的值(非常重要)
4.1 用中括号访问:字典名[键]
基本格式:
字典名[键]
例子:
person = {
"name": "小明",
"age": 18,
"city": "北京",
}
print(person["name"]) # 小明
print(person["age"]) # 18
print(person["city"]) # 北京
注意:
- 键是字符串时,要写上引号:
person["name"],不能写成person[name](那是变量名)。 - 如果访问一个不存在的键,会报
KeyError错误:
# print(person["height"]) # KeyError: 'height'
4.2 使用 get() 访问值(更安全)
get() 是字典的一个方法:
字典.get(键, 默认值)
- 如果键存在,返回对应的值;
- 如果键不存在,返回你给的“默认值”(不写默认值则返回
None),不会报错。
示例:
person = {"name": "小明", "age": 18}
print(person.get("name")) # 小明
print(person.get("city")) # None(没有 city 这个键)
print(person.get("city", "未知"))# 未知(给了默认值)
新手记忆:
如果不确定键一定存在,推荐用
get(),避免 KeyError。
5. 添加键—值对 & 修改字典中的值
5.1 添加键—值对(直接赋值)
语法:
字典[新键] = 新值
- 如果这个键不存在,就是添加新键—值对
- 如果这个键已存在,就是修改这个键对应的值
例子:
person = {
"name": "小明",
"age": 18,
}
# 添加一个新键 city
person["city"] = "北京"
print(person)
# {'name': '小明', 'age': 18, 'city': '北京'}
# 再添加一个键 hobby
person["hobby"] = "篮球"
print(person)
# {'name': '小明', 'age': 18, 'city': '北京', 'hobby': '篮球'}
5.2 修改已有键的值(也是用赋值)
person = {
"name": "小明",
"age": 18,
"city": "北京",
}
person["age"] = 20 # 修改年龄
person["city"] = "上海" # 修改城市
print(person)
# {'name': '小明', 'age': 20, 'city': '上海'}
你可以看到:
添加和修改的语法是一样的:
字典[键] = 值,区别在于这个键以前有没有存在。
5.3 先创建一个空字典,然后逐步添加
结合前面说的“空字典”,一个完整的例子:
person = {} # 先创建空字典
person["name"] = "小红"
person["age"] = 19
person["city"] = "广州"
print(person)
# {'name': '小红', 'age': 19, 'city': '广州'}
这种写法很常见,比如你先问用户一大堆信息,然后依次塞进这个字典。
6. 删除键—值对
有几种方式可以删除字典中的键—值对。
6.1 使用 del 删除指定键
语法:
del 字典[键]
例子:
person = {
"name": "小明",
"age": 18,
"city": "北京",
}
del person["city"]
print(person)
# {'name': '小明', 'age': 18}
注意:
- 如果键不存在,
del会报KeyError。
6.2 使用 pop() 删除并返回值
语法:
值 = 字典.pop(键, 默认值)
- 删除指定键,并返回它的值;
- 如果键不存在:
- 不写默认值:会报
KeyError - 写了默认值:返回默认值,不报错
- 不写默认值:会报
例子:
person = {"name": "小明", "age": 18}
age = person.pop("age")
print(age) # 18
print(person) # {'name': '小明'}
city = person.pop("city", "未知")
print(city) # 未知
print(person) # {'name': '小明'}
6.3 使用 popitem() 删除“最后一个添加的键—值对”
在 Python 3.7+ 中,字典是有插入顺序的,popitem() 会删除并返回“最后一个添加的键—值对”:
person = {
"name": "小明",
"age": 18,
"city": "北京",
}
item = person.popitem()
print(item) # ('city', '北京')
print(person) # {'name': '小明', 'age': 18}
返回的是一个二元组 (键, 值)。
6.4 使用 clear() 清空整个字典
person = {"name": "小明", "age": 18}
person.clear()
print(person) # {}
7. 最后一个值为什么也可以加逗号?
你可能注意到我在写字典时,经常这样写:
person = {
"name": "小明",
"age": 18,
"city": "北京", # 这里是“最后一行”,后面还是有逗号
}
问题:最后一行后面为什么也可以加逗号?
答案:这是 Python 语法允许的,主要是为了方便后期维护和修改代码。
好处:
- 以后你要在最后再加一行,不用再去上一行删逗号:
person = {
"name": "小明",
"age": 18,
"city": "北京",
"hobby": "篮球",
}
- 对比如果不允许最后一行加逗号:
- 原来最后一行没有逗号
- 你要插入一行时,得先给原本的“最后一行”加上逗号,再写新行,操作麻烦,还容易漏掉逗号导致语法错误
总结:
在字典(和列表、元组)中,最后一个元素后面写不写逗号都可以。
推荐风格:多行书写时,最后一项也保留一个逗号,更容易增删。
8. 字典的遍历(for 循环)
和列表一样,字典也可以用 for 遍历,但要注意:默认遍历的是“键”。
8.1 遍历所有键(key)
person = {
"name": "小明",
"age": 18,
"city": "北京",
}
for key in person:
print("键:", key)
等价写法:
for key in person.keys():
print("键:", key)
8.2 遍历所有值(value)
for value in person.values():
print("值:", value)
8.3 同时遍历键和值(最常用)
for key, value in person.items():
print(key, "=>", value)
items() 返回的其实是一系列 (键, 值) 的小元组,for key, value in ... 可以一行解包。
输出示例:
name => 小明
age => 18
city => 北京
新手建议:
需要同时拿到键和值时,优先使用
for key, value in dict.items(),写得最清晰。
9. 字典的嵌套与复杂结构
字典很强大的一点是:值可以是列表、也可以是字典。
这就可以构建非常灵活的数据结构,比如:
- “列表中存字典”
- “字典中存列表”
- “字典中存字典”
下面分开讲。
10. 字典中存储列表
场景例子:一个人有多个爱好、多门课程成绩,列表就很适合放在字典里。
student = {
"name": "小明",
"age": 18,
"hobbies": ["篮球", "吉他", "编程"], # 列表
}
10.1 访问和遍历这个列表
print(student["hobbies"])
# ['篮球', '吉他', '编程']
for hobby in student["hobbies"]:
print("爱好:", hobby)
输出:
爱好: 篮球
爱好: 吉他
爱好: 编程
10.2 添加列表元素
student["hobbies"].append("游泳")
print(student["hobbies"])
# ['篮球', '吉他', '编程', '游泳']
11. 字典中存储字典(嵌套字典)
场景例子:一个用户的“地址信息”又是一个结构化的内容(城市、街道、邮编等),很适合再用一个字典表示。
user = {
"username": "xiaoming",
"age": 18,
"address": {
"province": "北京",
"city": "北京市",
"district": "海淀区",
"detail": "中关村大街 1 号",
},
}
11.1 访问嵌套字典中的值
print(user["address"]["city"]) # 北京市
print(user["address"]["detail"]) # 中关村大街 1 号
理解方式:
user["address"]先拿到“地址”这个子字典- 再对这个子字典用
["city"]、["detail"]继续访问
11.2 遍历嵌套字典
for key, value in user["address"].items():
print(key, "=>", value)
输出类似:
province => 北京
city => 北京市
district => 海淀区
detail => 中关村大街 1 号
12. 列表中存储字典(很多“记录”的列表)
在实际项目中,非常常见的一种结构是:
“列表中每一项都是一个字典”——可以理解成多条“记录”。
例如,一个班级有多名学生:
students = [
{"name": "小明", "age": 18},
{"name": "小红", "age": 19},
{"name": "小刚", "age": 17},
]
12.1 遍历整个列表,访问每个字典
for student in students:
print("姓名:", student["name"], "年龄:", student["age"])
输出:
姓名: 小明 年龄: 18
姓名: 小红 年龄: 19
姓名: 小刚 年龄: 17
12.2 结合条件判断
例如,打印所有年龄大于等于 18 的学生:
for student in students:
if student["age"] >= 18:
print(student["name"], "已成年")
13. 复杂一点的综合示例
综合使用“字典中存列表”“字典中存字典”“列表中存字典”:
class_info = {
"name": "高一(1)班",
"monitor": "小明", # 班长
"students": [ # 学生列表(列表中每个元素都是一个字典)
{
"name": "小明",
"age": 16,
"scores": { # 字典中存字典
"math": 95,
"chinese": 88,
},
},
{
"name": "小红",
"age": 15,
"scores": {
"math": 90,
"chinese": 92,
},
},
],
}
13.1 遍历所有学生及成绩
print("班级名称:", class_info["name"])
print("班长:", class_info["monitor"])
for stu in class_info["students"]:
name = stu["name"]
age = stu["age"]
math = stu["scores"]["math"]
chinese = stu["scores"]["chinese"]
print(f"姓名:{name},年龄:{age},数学:{math},语文:{chinese}")
你会发现,字典 + 列表的组合,可以很自然地表达现实中的各种结构化信息。
14. 字典的一些常用方法补充
14.1 keys() / values() / items()
前面已经用过,简单总结:
person = {"name": "小明", "age": 18}
print(person.keys()) # dict_keys(['name', 'age'])
print(person.values()) # dict_values(['小明', 18])
print(person.items()) # dict_items([('name', '小明'), ('age', 18)])
一般配合 for 使用:
for key in person.keys():
print(key)
for value in person.values():
print(value)
for key, value in person.items():
print(key, value)
14.2 in 判断键是否存在
person = {"name": "小明", "age": 18}
print("name" in person) # True
print("city" in person) # False
if "city" not in person:
print("还没有城市信息")
注意:in 检查的是键,不是值。
15. 和列表一样,字典也有“长度”(len)
person = {"name": "小明", "age": 18, "city": "北京"}
print(len(person)) # 3(有 3 个键)
在遍历或判断是否为空时很常用:
if len(person) == 0:
print("字典是空的")
else:
print("字典里有数据")
16. 常见陷阱与小建议
16.1 KeyError:访问不存在的键
person = {"name": "小明"}
# print(person["age"]) # KeyError: 'age'
# 推荐用 get,避免报错
age = person.get("age", "未知")
print(age) # 未知
16.2 键必须是不可变类型
# 错误示例:列表不能当键
# d = {["a", "b"]: 123} # TypeError
16.3 字典是可变的,赋值是“引用同一个”
person1 = {"name": "小明"}
person2 = person1 # 两个变量指向同一个字典
person2["age"] = 18
print(person1) # {'name': '小明', 'age': 18}
print(person2) # {'name': '小明', 'age': 18}
如果想要复制一份新字典,用 copy():
person1 = {"name": "小明"}
person2 = person1.copy()
person2["age"] = 18
print(person1) # {'name': '小明'}
print(person2) # {'name': '小明', 'age': 18}