【python学习】字典(Dictionary)
目录
方式4:使用 fromkeys() 方法创建(快速创建“同值”字典)
方式3:使用 values()/items() 访问所有值/键值对
方式3:使用 popitem() 方法删除(删除最后一个键值对,返回元组)
方式4:使用 clear() 方法删除(清空字典,保留字典对象)

一、字典概述
1.1 什么是字典
字典是Python中一种**可变、无序(Python 3.7+ 后为有序)、键值对(key-value)** 结构的数据类型,用于存储具有映射关系的数据。类比现实生活中的字典,“键(key)”相当于字典中的“拼音/部首”,“值(value)”相当于对应的“汉字/解释”,通过键可以快速找到对应的值,查询效率远高于列表。
字典的核心特点:
-
键(key):唯一且不可变(可使用字符串、数字、元组,不可使用列表、字典等可变类型);
-
值(value):可任意类型(字符串、数字、列表、字典等均可),可重复;
-
可变:可动态添加、修改、删除键值对;
-
有序(Python 3.7+):插入顺序与遍历顺序一致(3.7之前无序)。
1.2 字典与其他数据类型的区别
|
数据类型 |
核心特点 |
适用场景 |
|---|---|---|
|
列表(list) |
有序、索引访问、元素可重复 |
存储有序的、可重复的一组数据 |
|
元组(tuple) |
有序、不可变、元素可重复 |
存储不可修改的有序数据 |
|
字典(dict) |
键值对、键唯一、可变(3.7+有序) |
存储具有映射关系的数据(如用户信息、配置参数) |
二、字典的基本操作
2.1 字典的创建
Python中创建字典有4种常用方式,根据场景选择合适的方式即可。
方式1:直接使用大括号 { } 创建(最常用)
语法:{key1: value1, key2: value2, ..., keyn: valuen}
# 示例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() 函数创建
语法1:dict(key1=value1, key2=value2, ...)(键无需加引号)
语法2:dict(可迭代对象)(如列表、元组,每个元素是长度为2的键值对)
# 语法1示例 student = dict(name="李四", age=19, gender="女", score=92) print(student) # 输出:{'name': '李四', 'age': 19, 'gender': '女', 'score': 92} # 语法2示例(列表嵌套元组) data = [("name", "王五"), ("age", 20), ("score", 88)] student2 = dict(data) print(student2) # 输出:{'name': '王五', 'age': 20, 'score': 88} # 语法2示例(元组嵌套列表) data2 = (["name", "赵六"], ["age", 21], ["score", 90]) student3 = dict(data2) print(student3) # 输出:{'name': '赵六', 'age': 21, 'score': 90}
方式3:字典推导式创建(进阶,简洁高效)
语法:{key: value for 变量 in 可迭代对象 [if 条件]}
# 示例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} # 示例3:结合两个列表创建字典(键来自list1,值来自list2) list1 = ["name", "age", "gender"] list2 = ["孙七", 18, "男"] student4 = {list1[i]: list2[i] for i in range(len(list1))} print(student4) # 输出:{'name': '孙七', 'age': 18, 'gender': '男'}
方式4:使用 fromkeys() 方法创建(快速创建“同值”字典)
语法:dict.fromkeys(可迭代对象, value),所有键对应的初始值均为value(默认None)
# 示例1:所有键的初始值为None keys = ["a", "b", "c"] dict1 = dict.fromkeys(keys) print(dict1) # 输出:{'a': None, 'b': None, 'c': None} # 示例2:所有键的初始值为0 dict2 = dict.fromkeys(keys, 0) print(dict2) # 输出:{'a': 0, 'b': 0, 'c': 0} # 注意:若value为可变类型(如列表),所有键共享同一个值(修改一个会影响所有) dict3 = dict.fromkeys(keys, []) dict3["a"].append(1) print(dict3) # 输出:{'a': [1], 'b': [1], 'c': [1]}(不推荐此用法)
2.2 字典的访问(获取值)
访问字典值的核心是“通过键访问”,有3种常用方式,各有优劣。
方式1:直接使用 [key] 访问(最常用)
语法:字典名[key],若key不存在,会报错 KeyError(重点注意)。
student = {"name": "张三", "age": 18, "score": 95} # 访问存在的键 print(student["name"]) # 输出:张三 print(student["age"]) # 输出:18 # 访问不存在的键(报错) # print(student["height"]) # 报错:KeyError: 'height'
方式2:使用 get() 方法访问(推荐,更安全)
语法:字典名.get(key, default=None),若key不存在,返回默认值(默认None,可自定义),不报错。
student = {"name": "张三", "age": 18, "score": 95} # 访问存在的键 print(student.get("name")) # 输出:张三 print(student.get("age", 0)) # 输出:18(key存在,默认值无效) # 访问不存在的键(不报错,返回默认值) print(student.get("height")) # 输出:None print(student.get("height", 175)) # 输出:175(自定义默认值)
方式3:使用 values()/items() 访问所有值/键值对
适用于需要遍历所有值或键值对的场景。
student = {"name": "张三", "age": 18, "score": 95} # 访问所有值(返回可迭代对象,可转成列表) values = student.values() print(values) # 输出:dict_values(['张三', 18, 95]) print(list(values)) # 输出:['张三', 18, 95] # 访问所有键值对(返回可迭代对象,每个元素是元组) items = student.items() print(items) # 输出:dict_items([('name', '张三'), ('age', 18), ('score', 95)]) for key, value in items: print(f"{key}: {value}") # 循环遍历所有键值对
2.3 字典的修改(修改键值对)
字典的修改主要是“修改已有键的值”,语法简单,直接赋值即可。
student = {"name": "张三", "age": 18, "score": 95} # 修改已有键的值 student["age"] = 19 # 修改age的值为19 student["score"] = 98 # 修改score的值为98 print(student) # 输出:{'name': '张三', 'age': 19, 'score': 98} # 注意:若key不存在,直接赋值会变成“添加键值对”(见2.4) student["height"] = 175 print(student) # 输出:{'name': '张三', 'age': 19, 'score': 98, 'height': 175}
2.4 字典的添加(添加新键值对)
有2种常用方式,直接赋值(最常用)和 update() 方法(批量添加)。
方式1:直接赋值添加(单个键值对)
student = {"name": "张三", "age": 18} # 添加单个新键值对 student["gender"] = "男" student["score"] = 95 print(student) # 输出:{'name': '张三', 'age': 18, 'gender': '男', 'score': 95}
方式2:使用 update() 方法添加(批量添加/合并)
语法:字典名.update(其他字典/可迭代对象),若有重复键,会覆盖原有值。
student = {"name": "张三", "age": 18} # 方式1:传入另一个字典(批量添加) new_info = {"gender": "男", "score": 95, "height": 175} student.update(new_info) print(student) # 输出:{'name': '张三', 'age': 18, 'gender': '男', 'score': 95, 'height': 175} # 方式2:传入可迭代对象(键值对形式) student.update([("hobby", "篮球"), ("grade", "高一")]) print(student) # 输出:新增hobby和grade键值对 # 方式3:传入关键字参数(键无需加引号) student.update(address="北京", phone="123456") print(student) # 输出:新增address和phone键值对 # 注意:重复键会覆盖 student.update({"age": 19, "score": 98}) print(student["age"], student["score"]) # 输出:19 98(原有值被覆盖)
2.5 字典的删除(删除键值对)
有4种常用方式,根据需求选择:del、pop()、popitem()、clear()。
方式1:使用 del 语句删除(彻底删除,无返回值)
语法:del 字典名[key],删除指定键值对;del 字典名,删除整个字典(无法再访问)。
student = {"name": "张三", "age": 18, "score": 95} # 删除指定键值对 del student["score"] print(student) # 输出:{'name': '张三', 'age': 18} # 删除不存在的键(报错) # del student["height"] # 报错:KeyError: 'height' # 删除整个字典(后续无法访问student) # del student # print(student) # 报错:NameError: name 'student' is not defined
方式2:使用 pop() 方法删除(删除并返回值,推荐)
语法:字典名.pop(key, default),删除指定key,返回对应value;若key不存在,返回默认值(不报错)。
student = {"name": "张三", "age": 18, "score": 95} # 删除存在的键,返回对应值 score = student.pop("score") print(score) # 输出:95 print(student) # 输出:{'name': '张三', 'age': 18} # 删除不存在的键,返回默认值(不报错) height = student.pop("height", 175) print(height) # 输出:175 print(student) # 字典无变化
方式3:使用 popitem() 方法删除(删除最后一个键值对,返回元组)
语法:字典名.popitem(),Python 3.7+ 删除最后插入的键值对,返回 (key, value) 元组;空字典调用会报错。
student = {"name": "张三", "age": 18, "score": 95} # 删除最后一个键值对(score:95) item = student.popitem() print(item) # 输出:('score', 95) print(student) # 输出:{'name': '张三', 'age': 18} # 再次删除(age:18) item2 = student.popitem() print(item2) # 输出:('age', 18) print(student) # 输出:{'name': '张三'}
方式4:使用 clear() 方法删除(清空字典,保留字典对象)
语法:字典名.clear(),清空字典内所有键值对,字典本身仍存在(变成空字典)。
student = {"name": "张三", "age": 18, "score": 95} # 清空字典 student.clear() print(student) # 输出:{}(空字典) print(type(student)) # 输出:<class 'dict'>(字典对象仍存在)
三、字典的进阶用法
3.1 字典的遍历(重点)
字典的遍历分为“遍历键”“遍历值”“遍历键值对”,其中“遍历键值对”最常用。
student = {"name": "张三", "age": 18, "gender": "男", "score": 95} # 1. 遍历所有键(3种方式,效果一致) # 方式1:直接遍历字典(默认遍历键) for key in student: print(key) # 输出:name、age、gender、score # 方式2:使用 keys() 方法(更直观) for key in student.keys(): print(key) # 方式3:转成列表后遍历(适合需要索引的场景) keys = list(student.keys()) for i in range(len(keys)): print(f"索引{i}:{keys[i]}") # 2. 遍历所有值(使用 values() 方法) for value in student.values(): print(value) # 输出:张三、18、男、95 # 3. 遍历所有键值对(使用 items() 方法,最常用) for key, value in student.items(): print(f"{key}: {value}") # 输出:name: 张三、age: 18 等 # 进阶:遍历中修改值(不能直接修改键) for key in student: if key == "age": student[key] = student[key] + 1 # 年龄加1 print(student["age"]) # 输出:19
3.2 字典的嵌套(高频使用)
字典的值可以是任何类型,当值为字典时,就构成了“嵌套字典”,用于存储更复杂的层级数据(如用户信息、商品信息)。
# 示例1:嵌套字典(用户信息,包含个人信息和成绩) user = { "basic_info": { "name": "张三", "age": 18, "gender": "男" }, "scores": { "math": 95, "chinese": 92, "english": 88 } } # 访问嵌套字典的值(逐层访问,先访问外层键,再访问内层键) print(user["basic_info"]["name"]) # 输出:张三 print(user["scores"]["math"]) # 输出:95 # 修改嵌套字典的值 user["basic_info"]["age"] = 19 user["scores"]["english"] = 90 print(user["basic_info"]["age"]) # 输出:19 print(user["scores"]["english"]) # 输出:90 # 添加嵌套字典的键值对 user["basic_info"]["address"] = "北京" user["scores"]["physics"] = 93 print(user) # 示例2:列表嵌套字典(多个用户信息) users = [ {"name": "张三", "age": 18, "score": 95}, {"name": "李四", "age": 19, "score": 92}, {"name": "王五", "age": 20, "score": 88} ] # 遍历列表中的字典 for user in users: print(f"姓名:{user['name']},年龄:{user['age']}")
3.3 字典的常用方法(补充)
除了上述操作,字典还有几个常用方法,整理如下(重点记忆标红):
|
方法 |
语法 |
功能 |
示例 |
|---|---|---|---|
|
keys() |
dict.keys() |
返回所有键的可迭代对象 |
student.keys() → dict_keys(['name', 'age']) |
|
values() |
dict.values() |
返回所有值的可迭代对象 |
student.values() → dict_values(['张三', 18]) |
|
items() |
dict.items() |
返回所有键值对的可迭代对象 |
student.items() → dict_items([('name', '张三')]) |
|
get() |
dict.get(key, default) |
获取键对应的值,不存在返回默认值 |
student.get("height", 175) → 175 |
|
update() |
dict.update(其他字典) |
批量添加/修改键值对 |
student.update({"gender": "男"}) |
|
pop() |
dict.pop(key, default) |
删除键值对,返回对应值 |
student.pop("age") → 18 |
|
popitem() |
dict.popitem() |
删除最后一个键值对,返回元组 |
student.popitem() → ('score', 95) |
|
clear() |
dict.clear() |
清空字典 |
student.clear() → {} |
|
copy() |
dict.copy() |
浅拷贝字典(修改拷贝后的字典不影响原字典) |
new_stu = student.copy() |
3.4 字典的浅拷贝与深拷贝(避坑重点)
当字典中包含可变类型的值(如列表、字典)时,直接赋值、浅拷贝、深拷贝的效果不同,容易踩坑,重点区分:
# 1. 直接赋值(引用,修改一个会影响另一个) dict1 = {"name": "张三", "hobbies": ["篮球", "游戏"]} dict2 = dict1 # 直接赋值,指向同一个内存地址 dict2["name"] = "李四" dict2["hobbies"].append("读书") print(dict1) # 输出:{'name': '李四', 'hobbies': ['篮球', '游戏', '读书']}(原字典被修改) # 2. 浅拷贝(copy() 方法,只拷贝外层字典,内层可变对象仍引用) dict3 = {"name": "张三", "hobbies": ["篮球", "游戏"]} dict4 = dict3.copy() # 浅拷贝 dict4["name"] = "李四" # 修改外层键的值,不影响原字典 dict4["hobbies"].append("读书") # 修改内层列表,影响原字典 print(dict3) # 输出:{'name': '张三', 'hobbies': ['篮球', '游戏', '读书']}(内层被修改) print(dict4) # 输出:{'name': '李四', 'hobbies': ['篮球', '游戏', '读书']} # 3. 深拷贝(需要导入copy模块,完全拷贝,内外层均独立) import copy dict5 = {"name": "张三", "hobbies": ["篮球", "游戏"]} dict6 = copy.deepcopy(dict5) # 深拷贝 dict6["name"] = "李四" dict6["hobbies"].append("读书") print(dict5) # 输出:{'name': '张三', 'hobbies': ['篮球', '游戏']}(原字典无变化) print(dict6) # 输出:{'name': '李四', 'hobbies': ['篮球', '游戏', '读书']}
四、字典的实战案例(巩固练习)
案例1:统计字符串中每个字符出现的次数
# 需求:统计字符串 "hello python python" 中每个字符出现的次数 str1 = "hello python python" count_dict = {} # 空字典,用于存储字符: 次数 for char in str1: if char == " ": # 跳过空格,不统计 continue # 若字符已在字典中,次数+1;否则添加到字典,次数设为1 if char in count_dict: count_dict[char] += 1 else: count_dict[char] = 1 # 遍历输出结果 for char, count in count_dict.items(): print(f"字符 '{char}' 出现了 {count} 次") # 输出结果(示例): # 字符 'h' 出现了 1 次 # 字符 'e' 出现了 1 次 # 字符 'l' 出现了 2 次 # ...(其余字符省略)
案例2:存储学生信息并实现查询、修改功能
# 需求:创建学生信息字典,实现“查询学生信息”“修改学生年龄”“添加学生成绩”功能 students = { "1001": {"name": "张三", "age": 18, "scores": {"math": 95, "chinese": 92}}, "1002": {"name": "李四", "age": 19, "scores": {"math": 88, "chinese": 90}}, "1003": {"name": "王五", "age": 20, "scores": {"math": 91, "chinese": 87}} } # 1. 查询学生信息(根据学号) def query_student(student_id): if student_id in students: info = students[student_id] print(f"学号:{student_id}") print(f"姓名:{info['name']}") print(f"年龄:{info['age']}") print(f"成绩:数学 {info['scores']['math']},语文 {info['scores']['chinese']}") else: print("该学号不存在!") # 2. 修改学生年龄(根据学号) def update_age(student_id, new_age): if student_id in students: students[student_id]["age"] = new_age print(f"学号 {student_id} 的年龄已修改为 {new_age}") else: print("该学号不存在!") # 3. 添加学生成绩(根据学号,新增科目) def add_score(student_id, subject, score): if student_id in students: students[student_id]["scores"][subject] = score print(f"学号 {student_id} 已添加 {subject} 成绩:{score}") else: print("该学号不存在!") # 调用函数测试 query_student("1001") update_age("1001", 19) add_score("1001", "english", 93) print("\n修改后的学生信息:") query_student("1001")
案例3:字典推导式实战(筛选并重组数据)
# 需求:有一个字典,存储学生姓名和总分,筛选出总分≥90的学生,并重组成“姓名: 等级”的字典(≥90为A,80-89为B,70-79为C) student_scores = {"张三": 95, "李四": 88, "王五": 92, "赵六": 75, "孙七": 82} # 字典推导式筛选+重组 grade_dict = { name: "A" if score >= 90 else "B" if score >= 80 else "C" for name, score in student_scores.items() if score >= 70 # 筛选出总分≥70的学生 } print(grade_dict) # 输出:{'张三': 'A', '李四': 'B', '王五': 'A', '赵六': 'C', '孙七': 'B'}
五、常见问题与避坑指南
5.1 常见错误及解决方法
-
错误1:KeyError(键不存在) 原因:使用 [key] 访问不存在的键; 解决:使用 get() 方法并设置默认值,或先判断键是否存在(if key in 字典名)。
-
错误2:TypeError(键不可变) 原因:使用列表、字典等可变类型作为键; 解决:将键改为字符串、数字、元组等不可变类型。
-
错误3:修改字典时“共享值”问题 原因:使用 fromkeys() 方法创建字典,且value为可变类型(如列表); 解决:避免用 fromkeys() 创建可变值的字典,改用循环添加。
-
错误4:遍历字典时修改键 原因:字典遍历过程中,不能直接添加/删除键(会导致遍历异常); 解决:先将键转成列表(list(字典名.keys())),再遍历列表修改。
5.2 实用技巧
-
判断键是否存在:使用
key in 字典名(推荐),比 try-except 更简洁。 -
快速获取字典的所有键/值:使用
list(字典名.keys())、list(字典名.values()),方便索引访问。 -
字典排序:Python 3.7+ 字典本身有序,若需按键/值排序,可使用
sorted(字典名.items(), key=lambda x: x[0])(按键排序)。 -
空字典判断:使用
if not 字典名(空字典返回True,非空返回False)。
六、总结
字典是Python中最常用的数据类型之一,核心是“键值对映射”,重点掌握以下内容:
-
基础操作:创建、访问(get()方法推荐)、修改、添加、删除;
-
进阶操作:遍历(items()方法最常用)、嵌套字典、字典推导式;
-
避坑重点:键的不可变性、浅拷贝与深拷贝的区别、KeyError的避免;
-
实战应用:利用字典存储映射关系,如统计、配置、用户信息管理等。
多练习案例(如字符统计、信息管理),能快速掌握字典的使用技巧,后续结合列表、函数等知识,可实现更复杂的功能。
更多推荐



所有评论(0)