字典(dict)是Python中最常用的内置数据结构之一,采用“键-值(key-value)”对的形式存储数据,具有高效的查找、插入和删除特性。它广泛应用于数据分析、配置存储、数据映射等场景,是Python编程必备的核心知识点。本文档将系统梳理字典的核心操作,从基础到进阶逐步讲解,辅以可直接运行的代码示例,助力快速掌握。
一、字典的基础认知
1.1 定义与特点
字典是一种无序、可变的集合类型,其核心特征如下:
•元素格式:每个元素由“键(key)”和“值(value)”组成,键与值用冒号(:)分隔,元素之间用逗号(,)分隔,整体包裹在大括号({})中;
•键的约束:键必须是不可变类型(如字符串、数字、元组),且不能重复;值可以是任意类型(字符串、数字、列表、字典等),支持重复;
•无序性:Python 3.7之前字典是无序的,Python 3.7及以上版本保证插入顺序与遍历顺序一致;
•可变性:可动态添加、修改、删除键值对。
1.2 字典的创建
Python提供多种创建字典的方式,最常用的有以下4种:
方式1:直接使用大括号创建(最常用)
python# 创建空字典empty_dict = {}print(empty_dict, type(empty_dict)) # 输出:{} <class 'dict'># 创建带初始键值对的字典(键为字符串、数字,值为不同类型)student = {"name": "张三","age": 20,"score": [90, 85, 95],"is_pass": True}print(student) # 输出:{'name': '张三', 'age': 20, 'score': [90, 85, 95], 'is_pass': True} |
方式2:使用dict()函数创建
python# 方式2.1:通过关键字参数创建fruit = dict(apple=5, banana=3, orange=4)print(fruit) # 输出:{'apple': 5, 'banana': 3, 'orange': 4}# 方式2.2:通过可迭代对象(如列表、元组)创建(元素需为二元组)color = dict([("red", "#FF0000"), ("green", "#00FF00"), ("blue", "#0000FF")])print(color) # 输出:{'red': '#FF0000', 'green': '#00FF00', 'blue': '#0000FF'} |
方式3:使用字典推导式创建(进阶,后续详解)
python# 从列表推导生成字典(键为1-5的数字,值为键的平方)square_dict = {x: x*x for x in range(1, 6)}print(square_dict) # 输出:{1: 1, 2: 4, 3: 9, 4: 16, 5: 25} |
方式4:使用fromkeys()方法创建(快速创建指定键、默认值的字典)
python# 所有键的默认值为Nonekeys = ["a", "b", "c"]default_dict = dict.fromkeys(keys)print(default_dict) # 输出:{'a': None, 'b': None, 'c': None}# 所有键的默认值指定为0count_dict = dict.fromkeys(keys, 0)print(count_dict) # 输出:{'a': 0, 'b': 0, 'c': 0} |
二、字典的核心基本操作
2.1 访问字典的值
字典通过“键”访问对应的值,主要有2种方式,核心是“键必须存在”(否则报错,可通过异常处理或get()方法规避)。
方式1:通过“键名[]”访问(最常用)
pythonstudent = {"name": "张三", "age": 20, "score": [90, 85, 95]}# 访问存在的键print(student["name"]) # 输出:张三print(student["score"][1]) # 访问值为列表的元素,输出:85# 访问不存在的键(会报错KeyError)# print(student["gender"]) # 报错:KeyError: 'gender' |
方式2:通过get()方法访问(推荐,可处理键不存在的情况)
语法:dict.get(key, default=None),当键不存在时,返回默认值(默认None,不会报错)。
pythonstudent = {"name": "张三", "age": 20}# 访问存在的键print(student.get("name")) # 输出:张三# 访问不存在的键,返回默认值print(student.get("gender")) # 输出:Noneprint(student.get("gender", "未知")) # 自定义默认值,输出:未知 |
2.2 添加/修改键值对
字典是可变的,可通过“键名[]”或update()方法动态添加、修改键值对。
方式1:通过“键名[]”添加/修改
逻辑:若键已存在,则修改对应的值;若键不存在,则添加新的键值对。
pythonstudent = {"name": "张三", "age": 20}# 修改已存在的键student["age"] = 21print(student) # 输出:{'name': '张三', 'age': 21}# 添加新的键值对student["gender"] = "男"student["address"] = "北京"print(student) # 输出:{'name': '张三', 'age': 21, 'gender': '男', 'address': '北京'} |
方式2:通过update()方法批量添加/修改
语法:dict.update(other_dict/iterable),可接收字典或可迭代的二元组,批量更新键值对。
pythonstudent = {"name": "张三", "age": 20}# 传入字典批量修改/添加update_info = {"age": 21, "gender": "男", "score": 90}student.update(update_info)print(student) # 输出:{'name': '张三', 'age': 21, 'gender': '男', 'score': 90}# 传入二元组列表批量添加student.update([("address", "北京"), ("class", "大一")])print(student) # 输出:{'name': '张三', 'age': 21, 'gender': '男', 'score': 90, 'address': '北京', 'class': '大一'} |
2.3 删除字典元素/字典
删除操作包括删除指定键值对、删除所有元素、删除整个字典,常用函数有del、pop()、popitem()、clear()。
方式1:del语句(删除指定键值对或整个字典)
pythonstudent = {"name": "张三", "age": 20, "gender": "男"}# 删除指定键值对del student["gender"]print(student) # 输出:{'name': '张三', 'age': 20}# 删除整个字典(删除后字典对象不存在,再访问会报错)del student# print(student) # 报错:NameError: name 'student' is not defined |
方式2:pop()方法(删除指定键值对,返回对应的值)
语法:dict.pop(key, default),删除指定键,返回对应的值;若键不存在,返回默认值(不指定则报错)。
pythonstudent = {"name": "张三", "age": 20, "gender": "男"}# 删除存在的键,返回对应值age = student.pop("age")print(age) # 输出:20print(student) # 输出:{'name': '张三', 'gender': '男'}# 删除不存在的键,指定默认值score = student.pop("score", 0)print(score) # 输出:0# 删除不存在的键,不指定默认值(报错)# student.pop("score") # 报错:KeyError: 'score' |
方式3:popitem()方法(删除最后插入的键值对,返回该键值对元组)
Python 3.7+版本中,popitem()删除最后插入的元素;3.7之前删除随机元素(因字典无序)。
pythonstudent = {"name": "张三", "age": 20, "gender": "男"}# 删除最后插入的键值对(gender)last_item = student.popitem()print(last_item) # 输出:('gender', '男')print(student) # 输出:{'name': '张三', 'age': 20} |
方式4:clear()方法(清空字典所有元素,保留字典对象)
pythonstudent = {"name": "张三", "age": 20, "gender": "男"}# 清空字典student.clear()print(student) # 输出:{}(字典对象仍存在,只是无元素) |
三、字典的进阶操作
3.1 字典的遍历
字典支持遍历键、值、键值对,常用for循环结合keys()、values()、items()方法实现。
遍历1:遍历所有键(默认遍历方式,或用keys()方法)
pythonstudent = {"name": "张三", "age": 20, "gender": "男"}# 方式1:默认遍历键for key in student:print(key) # 输出:name、age、gender(顺序与插入一致)# 方式2:用keys()方法(明确遍历键,更易读)for key in student.keys():print(key) # 输出结果同上 |
遍历2:遍历所有值(用values()方法)
pythonstudent = {"name": "张三", "age": 20, "gender": "男"}for value in student.values():print(value) # 输出:张三、20、男 |
遍历3:遍历所有键值对(用items()方法,最常用)
items()方法返回包含所有键值对的元组列表,可通过“键, 值”解包遍历。
pythonstudent = {"name": "张三", "age": 20, "gender": "男"}for key, value in student.items():print(f"{key}: {value}")# 输出:# name: 张三# age: 20# gender: 男 |
3.2 字典推导式(快速构建字典)
类似列表推导式,字典推导式通过简洁语法快速生成字典,格式:{键表达式: 值表达式 for 变量 in 可迭代对象 if 条件}。
示例1:基础推导(键值一一映射)
python# 生成键为字母a-e,值为字母大写的字典upper_dict = {chr(97+i): chr(65+i) for i in range(5)}print(upper_dict) # 输出:{'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D', 'e': 'E'} |
示例2:带条件的推导(筛选元素)
python# 生成键为1-10的偶数,值为键的平方的字典even_square = {x: x*x for x in range(1, 11) if x % 2 == 0}print(even_square) # 输出:{2: 4, 4: 16, 6: 36, 8: 64, 10: 100} |
示例3:两个列表映射成字典
pythonkeys = ["name", "age", "gender"]values = ["李四", 22, "女"]# 用zip()函数将两个列表配对,再推导成字典student = {k: v for k, v in zip(keys, values)}print(student) # 输出:{'name': '李四', 'age': 22, 'gender': '女'} |
3.3 字典的常用内置方法
除上述操作对应的方法外,字典还有以下常用内置方法,提升操作效率:
1. keys()/values()/items():获取键/值/键值对(返回可迭代对象)
pythonstudent = {"name": "张三", "age": 20}# 获取所有键,转换为列表(可迭代对象需转换才能用索引)keys = list(student.keys())print(keys) # 输出:['name', 'age']# 获取所有值,转换为列表values = list(student.values())print(values) # 输出:['张三', 20]# 获取所有键值对,转换为列表items = list(student.items())print(items) # 输出:[('name', '张三'), ('age', 20)] |
2. copy():复制字典(浅拷贝)
注意:直接用“新字典=旧字典”是引用赋值(修改新字典会影响旧字典),copy()是浅拷贝(只复制表层键值对,值为可变类型时仍会关联)。
python# 1. 引用赋值(关联)dict1 = {"a": 1, "b": [2, 3]}dict2 = dict1dict2["a"] = 10dict2["b"].append(4)print(dict1) # 输出:{'a': 10, 'b': [2, 3, 4]}(dict1被修改)# 2. 浅拷贝(表层独立,深层可变类型仍关联)dict3 = dict1.copy()dict3["a"] = 20dict3["b"].append(5)print(dict1) # 输出:{'a': 10, 'b': [2, 3, 4, 5]}(dict1的b列表仍被修改)print(dict3) # 输出:{'a': 20, 'b': [2, 3, 4, 5]}(dict3的a独立) |
3. setdefault():获取键的值,不存在则添加键值对
语法:dict.setdefault(key, default=None),功能类似get(),但当键不存在时,会自动添加该键并赋值默认值。
pythonstudent = {"name": "张三", "age": 20}# 键存在,返回对应值name = student.setdefault("name", "未知")print(name) # 输出:张三print(student) # 无变化:{'name': '张三', 'age': 20}# 键不存在,添加键值对并返回默认值gender = student.setdefault("gender", "未知")print(gender) # 输出:未知print(student) # 输出:{'name': '张三', 'age': 20, 'gender': '未知'} |
四、字典操作的注意事项
•键的不可变性:字典的键必须是不可变类型(字符串、数字、元组),不能用列表、字典等可变类型作为键,否则报错。示例:dict1 = {[1,2]: 3}→ 报错:TypeError: unhashable type: 'list'
•键的唯一性:字典中不能有重复的键,若创建时重复,后定义的键值对会覆盖前一个。示例:dict2 = {"a":1, "a":2}→ 结果:{a:2}
•字典的可变性:字典本身是可变的,但键的不可变性不影响字典的修改操作(修改的是键对应的值,而非键本身)。
•浅拷贝与深拷贝:若字典的值包含可变类型(列表、字典),浅拷贝(copy())无法完全独立,需用copy.deepcopy()实现深拷贝(需导入copy模块)。示例:import copydict4 = {"a": [1,2]}dict5 = copy.deepcopy(dict4)dict5["a"].append(3)print(dict4) # 输出:{'a': [1,2]}(完全独立,不影响)
•字典的遍历效率:字典的查找、遍历效率远高于列表(字典底层是哈希表,时间复杂度O(1),列表是O(n)),数据量大时优先用字典存储需频繁查找的数据。
五、字典的应用场景举例
场景1:存储结构化数据
python# 存储多个学生信息(字典嵌套列表)students = [{"name": "张三", "age": 20, "score": 90},{"name": "李四", "age": 21, "score": 85},{"name": "王五", "age": 20, "score": 95}]# 遍历获取所有学生姓名for s in students:print(s["name"]) # 输出:张三、李四、王五 |
场景2:数据统计与计数
python# 统计列表中元素出现的次数fruits = ["apple", "banana", "apple", "orange", "banana", "apple"]count = {}for fruit in fruits:# 若元素已存在,计数+1;否则添加元素,计数=1count[fruit] = count.get(fruit, 0) + 1print(count) # 输出:{'apple': 3, 'banana': 2, 'orange': 1} |
场景3:配置参数存储
python# 存储程序配置参数config = {"host": "localhost","port": 8080,"timeout": 30,"debug": True}# 读取配置print(f"连接地址:{config['host']}:{config['port']}") # 输出:连接地址:localhost:8080 |
总结:字典是Python中灵活高效的数据结构,核心是“键-值”映射关系。掌握本文档中的创建、访问、修改、删除、遍历等操作,结合实际场景灵活运用,能大幅提升编程效率。建议多通过代码练习巩固各方法的使用,重点关注键的约束、浅/深拷贝、推导式等进阶知识点。