Python入门第6章:字典(键值对数据结构)
大家好,欢迎来到Python入门系列的第6章内容!在前5章里,我们学会了变量、数据类型、运算符、if语句等基础知识点,也接触了列表、元组这两种序列数据结构------它们都是通过"索引"来访问元素,适合存储有序的、可重复的一组数据。但在实际编程中,我们经常会遇到"通过一个标识,快速找到对应数据"的场景,比如通过姓名找成绩、通过ID找用户信息,这时候列表和元组就显得不够高效了。
今天我们要学习的字典(dict),就是为解决这种"映射关系"而生的核心数据结构。它像一本现实中的字典,"拼音/部首"对应"键(key)","汉字/解释"对应"值(value)",通过键可以快速定位到对应的值,查询效率远超列表。这一章内容不难,但使用频率极高,是后续学习复杂程序、处理真实数据的基础,咱们正式开始!
一、为什么需要字典?先看一个场景
假设我们要存储一个学生的信息,包含姓名、年龄、性别、成绩。如果用之前学的列表,会这样写:
python
student = ["张三", 18, "男", 95]
# 访问成绩,需要记住索引(3)
print("学生成绩:", student[3])
这种方式有两个明显的问题:一是必须记住每个数据对应的索引,一旦列表元素顺序调整,所有索引访问都会出错;二是如果数据量很大,要找到某个信息,需要逐个遍历列表,效率很低。
而用字典来存储,就简洁又高效得多:
python
student = {"name": "张三", "age": 18, "gender": "男", "score": 95}
# 访问成绩,直接用"键"查找,无需记索引
print("学生成绩:", student["score"])
可以看到,字典通过"键值对"的形式存储数据,键是唯一的标识,值是对应的数据,通过键就能直接找到值,这就是字典的核心优势------键值映射,快速查找。
二、字典的核心定义与特点
字典是Python中一种**可变、键值对(key-value)**结构的数据类型,Python 3.7+版本后,字典会保持插入时的顺序(3.7之前为无序),其核心特点的可以总结为4点,必须牢记:
-
键(key)唯一:同一个字典中,键不能重复,重复赋值会覆盖原来的值(比如{"name": "张三", "name": "李四"},最终name的值是"李四")。
-
键不可变:键必须是"不可变类型",比如字符串、数字、元组;列表、字典等可变类型不能作为键,否则会报错。
-
值(value)可任意:值可以是任意数据类型,包括字符串、数字、列表、字典甚至元组,也可以重复。
-
字典可变:可以动态添加、修改、删除字典中的键值对,这一点和列表类似,和元组不同。
这里我们可以对比一下字典和之前学的列表、元组,更清晰地理解它们的区别:
| 数据类型 | 核心特点 | 访问方式 | 适用场景 |
|---|---|---|---|
| 列表(list) | 有序、可变、元素可重复 | 通过索引(0开始) | 存储有序的、可重复的一组数据 |
| 元组(tuple) | 有序、不可变、元素可重复 | 通过索引(0开始) | 存储不可修改的有序数据 |
| 字典(dict) | 键值对、键唯一、可变(3.7+有序) | 通过键(key) | 存储具有映射关系的数据(如用户信息、配置参数) |
三、字典的创建(4种常用方式)
创建字典有多种方式,其中最常用的是"大括号创建",其他方式根据场景灵活选择,我们逐一讲解,重点掌握前2种。
1. 大括号 { } 创建(最常用)
这是最简洁、最常用的创建方式,语法格式:{key1: value1, key2: value2, ..., keyn: valuen},键和值之间用冒号(:)连接,多个键值对之间用逗号(,)分隔。
python
# 1. 普通字典(键为字符串,值为不同类型)
student = {"name": "张三", "age": 18, "gender": "男", "score": 95}
print(student) # 输出:{'name': '张三', 'age': 18, 'gender': '男', 'score': 95}
# 2. 值为列表/元组(值可任意类型)
info = {"id": 1001, "hobbies": ["篮球", "游戏"], "is_student": True}
print(info) # 输出:{'id': 1001, 'hobbies': ['篮球', '游戏'], 'is_student': True}
# 3. 空字典(用于后续动态添加数据)
empty_dict = {}
print(type(empty_dict)) # 输出:<class 'dict'>
2. dict() 函数创建(推荐,更规范)
使用内置函数dict()创建字典,有两种常用写法,适合批量创建或代码更规范的场景。
python
# 写法1:直接传入键值对参数(键无需加引号)
student1 = dict(name="李四", age=19, gender="女", score=92)
print(student1) # 输出:{'name': '李四', 'age': 19, 'gender': '女', 'score': 92}
# 写法2:传入可迭代对象(如列表、元组,每个元素是长度为2的键值对)
data = [("name", "王五"), ("age", 20), ("score", 88)]
student2 = dict(data)
print(student2) # 输出:{'name': '王五', 'age': 20, 'score': 88}
3. 字典推导式创建(进阶,简洁高效)
和列表推导式类似,字典推导式可以快速生成字典,适合根据已有数据批量生成键值对,入门阶段了解即可,后续会详细拓展。
python
# 示例1:生成"数字: 平方"的字典
square_dict = {i: i**2 for i in range(1, 6)}
print(square_dict) # 输出:{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# 示例2:筛选偶数对应的平方
even_square = {i: i**2 for i in range(1, 10) if i % 2 == 0}
print(even_square) # 输出:{2: 4, 4: 16, 6: 36, 8: 64}
4. fromkeys() 方法创建(快速创建"同值"字典)
如果需要创建一个"多个键对应同一个值"的字典,用fromkeys()方法非常高效,语法:dict.fromkeys(keys, value),value可选,默认是None。
python
# 生成键为("a", "b", "c")、值默认None的字典
default_dict = dict.fromkeys(("a", "b", "c"))
print(default_dict) # 输出:{'a': None, 'b': None, 'c': None}
# 生成键为1-3、值统一为0的字典
zero_dict = dict.fromkeys(range(1, 4), 0)
print(zero_dict) # 输出:{1: 0, 2: 0, 3: 0}
四、字典的核心操作(增删改查,必掌握)
字典的核心操作围绕"键值对"展开,即添加、修改、删除键值对,以及查询值,这部分是重点,每个操作都要掌握,搭配示例练习。
1. 查:获取字典中的值(2种常用方式)
获取值是字典最常用的操作,有两种方式,重点区分它们的差异,避免踩坑。
python
student = {"name": "张三", "age": 18, "gender": "男", "score": 95}
# 方式1:直接用 字典[键] 访问(最常用,但键不存在会报错)
print(student["name"]) # 输出:张三
# print(student["height"]) # 报错:KeyError: 'height'(键不存在)
# 方式2:用 get() 方法访问(推荐,更安全,键不存在返回默认值)
print(student.get("age")) # 输出:18
# 键不存在时,返回指定默认值(此处默认值为"未知")
print(student.get("height", "未知")) # 输出:未知
# 键不存在且未指定默认值,返回None
print(student.get("height")) # 输出:None
易错点提醒:新手常因"键不存在"报错(KeyError),建议优先使用get()方法,尤其是在不确定键是否存在的场景(如处理用户输入、读取配置)。
补充:如果想获取字典所有的键、所有的值、所有的键值对,可以用这三个方法:
python
print(student.keys()) # 获取所有键,输出:dict_keys(['name', 'age', 'gender', 'score'])
print(student.values()) # 获取所有值,输出:dict_values(['张三', 18, '男', 95])
print(student.items()) # 获取所有键值对,输出:dict_items([('name', '张三'), ('age', 18), ('gender', '男'), ('score', 95)])
2. 增:添加新的键值对(2种方式)
字典是可变的,可以随时添加新的键值对,两种方式按需选择。
python
student = {"name": "张三", "age": 18, "gender": "男"}
# 方式1:直接赋值(最常用,键不存在则新增)
student["score"] = 95 # 新增键值对:"score": 95
print(student) # 输出:{'name': '张三', 'age': 18, 'gender': '男', 'score': 95}
# 方式2:用 update() 方法(批量添加/合并字典)
# 批量添加多个键值对
student.update({"height": 175, "class": "高一(1)班"})
print(student) # 输出包含新增的height和class键值对
# 合并另一个字典
other_info = {"hobby": "篮球", "address": "北京"}
student.update(other_info)
print(student) # 合并后包含other_info的所有键值对
3. 改:修改已有键值对
修改的逻辑很简单:键已存在时,直接赋值就是修改,和添加的方式一样,区别在于键是否存在。
python
student = {"name": "张三", "age": 18, "gender": "男", "score": 95}
# 键"age"已存在,直接赋值修改
student["age"] = 19
# 键"score"已存在,修改分数
student["score"] = 98
print(student) # 输出:{'name': '张三', 'age': 19, 'gender': '男', 'score': 98}
注意:字典的键是唯一的,重复赋值会直接覆盖原有值,不会报错,这一点要注意,避免误修改。
4. 删:删除字典中的键值对(4种方式)
删除操作有4种常用方式,分别对应不同的需求,重点掌握前2种。
python
student = {"name": "张三", "age": 18, "gender": "男", "score": 95}
# 方式1:del 语句(彻底删除,无返回值,键不存在会报错)
del student["gender"] # 删除键为"gender"的键值对
print(student) # 输出:{'name': '张三', 'age': 18, 'score': 95}
# del student["height"] # 报错:KeyError: 'height'
# 方式2:pop() 方法(删除并返回对应的值,推荐,键不存在可指定默认值)
score = student.pop("score") # 删除"score"键,返回对应的值95
print(score) # 输出:95
print(student) # 输出:{'name': '张三', 'age': 18}
# 键不存在时,指定默认值避免报错
height = student.pop("height", "未知")
print(height) # 输出:未知
# 方式3:popitem() 方法(删除最后一个键值对,返回该键值对元组)
item = student.popitem()
print(item) # 输出:('age', 18)(Python 3.7+ 按插入顺序删除最后一个)
print(student) # 输出:{'name': '张三'}
# 方式4:clear() 方法(清空字典,保留字典对象,仅删除所有键值对)
student.clear()
print(student) # 输出:{}
五、字典的遍历(重点,常用场景)
遍历字典就是依次获取字典中的键、值或键值对,常用的遍历方式有3种,结合for循环使用,覆盖大部分场景。
python
student = {"name": "张三", "age": 18, "gender": "男", "score": 95}
# 方式1:遍历字典的所有键(默认遍历键,最简洁)
for key in student:
print("键:", key, ",值:", student[key])
# 方式2:遍历字典的所有键值对(用items()方法,最常用)
for key, value in student.items():
print(f"键:{key},值:{value}")
# 方式3:单独遍历所有值(用values()方法)
for value in student.values():
print("值:", value)
运行结果(方式2):
python
键:name,值:张三
键:age,值:18
键:gender,值:男
键:score,值:95
小贴士:遍历字典时,优先使用items()方法,直接获取键和值,代码更简洁;如果只需要值,再用values()方法,避免冗余代码。
六、字典的嵌套(进阶,高频使用)
当需要存储复杂数据(比如多个学生的信息、用户的详细配置)时,我们可以在字典中嵌套字典、列表,这就是字典的嵌套,也是实际开发中非常常用的技巧。
示例1:字典嵌套字典(存储多个学生信息)
python
# 字典嵌套:key是学生ID,value是每个学生的信息字典
students = {
1001: {"name": "张三", "age": 18, "score": 95},
1002: {"name": "李四", "age": 19, "score": 92},
1003: {"name": "王五", "age": 20, "score": 88}
}
# 访问1002号学生的姓名
print(students[1002]["name"]) # 输出:李四
# 访问1003号学生的分数
print(students[1003].get("score")) # 输出:88
# 修改1001号学生的年龄
students[1001]["age"] = 19
print(students[1001]) # 输出:{'name': '张三', 'age': 19, 'score': 95}
示例2:字典嵌套列表(存储用户的爱好、联系方式等)
python
user = {
"name": "张三",
"age": 18,
"hobbies": ["篮球", "游戏", "编程"], # 嵌套列表
"contact": {"phone": "13800138000", "email": "zhangsan@example.com"} # 嵌套字典
}
# 访问用户的第一个爱好
print(user["hobbies"][0]) # 输出:篮球
# 访问用户的邮箱
print(user["contact"]["email"]) # 输出:zhangsan@example.com
# 给用户添加一个爱好
user["hobbies"].append("看书")
print(user["hobbies"]) # 输出:['篮球', '游戏', '编程', '看书']
注意:字典嵌套时,访问元素要"逐层访问",比如要访问邮箱,先找到contact键对应的字典,再找email键,不能直接写user["email"]。
七、常见易错点总结(必看,避坑关键)
入门阶段,操作字典很容易踩坑,结合全球开发者的高频错误统计,总结5个最常见的错误,帮大家避坑:
-
KeyError报错 :直接用
字典[键]访问不存在的键,导致报错。解决方法:优先用get()方法,或先判断键是否存在(if 键 in 字典:)。 -
用可变类型作为键:把列表、字典等可变类型当作键,导致TypeError报错。记住:键只能是字符串、数字、元组等不可变类型。
-
重复键覆盖值 :无意之间重复定义同一个键,后赋值的value会覆盖前值,导致数据丢失。比如
{"name": "张三", "name": "李四"},最终name的值是"李四"。 -
字典未初始化就赋值 :还没创建字典对象,就直接给键赋值,导致NameError报错。解决方法:先通过
{}或dict()初始化字典。 -
嵌套字典访问错误 :访问嵌套字典时,跳过中间层级,直接访问内层键。比如
user["email"],正确写法是user["contact"]["email"]。
八、实战练习(巩固知识点)
学完字典的核心操作,动手练习才能真正掌握,这里给大家3个练习题目,从简单到复杂,结合之前学的if语句,巩固知识点:
-
简单:创建一个字典,存储自己的信息(姓名、年龄、性别、爱好),然后用get()方法获取自己的爱好,若爱好不存在,返回"无"。
-
中等:创建一个字典存储3个商品的信息(商品名、价格、库存),遍历字典,打印出所有价格大于50的商品信息。
-
进阶:创建一个嵌套字典,存储2个班级的信息(班级名、班主任、3个学生的姓名和成绩),然后修改其中一个学生的成绩,并添加一个新的学生到对应班级。
提示:练习时可以结合if语句、for循环,比如中等题中,遍历商品时用if判断价格是否大于50,再打印信息。练习答案会放在下一章开头哦~
九、本章小结
本章我们学会了Python中最常用的键值对数据结构------字典,掌握了它的创建、增删改查、遍历、嵌套等核心操作,也了解了字典的核心特点和常见易错点。
核心要点回顾:
-
字典的核心是"键值映射",通过键快速查找值,效率远高于列表,适合存储有映射关系的数据。
-
键的两个核心要求:唯一、不可变;值可以是任意类型,可重复。
-
核心操作:查(优先用get())、增(直接赋值/updat())、改(直接赋值)、删(del/pop())。
-
字典嵌套是处理复杂数据的常用技巧,访问时要逐层访问。
字典是Python编程中不可或缺的工具,后续学习函数、模块、数据处理时,都会频繁用到它。下一章我们会学习循环语句(for、while),结合字典和if语句,就能写出更复杂、更实用的程序啦!
如果大家在练习中遇到问题,欢迎在评论区留言,我会一一解答。我们下一章再见!