Python字典核心编程必备技能建议收藏前言大家好我是[你的名字]。在日常Python开发中字典dict绝对是我用得最频繁的数据结构没有之一。无论是处理JSON数据、缓存配置还是做计数器、去重字典都扮演着至关重要的角色。今天这篇文章我想把自己对字典的理解系统性地整理出来从基础用法到底层原理再到一些容易被忽视的“坑”希望能帮你彻底掌握Python字典。话不多说我们直接开始。一、什么是字典字典是Python内置的一种可变、无序的容器模型以“键值对”key: value的形式存储数据。你可以把它想象成一个现实中的电话本通过人名键就能快速找到电话号码值而不需要从头翻到尾。1.1 字典的创建方式python# 方式一花括号最常用 user {name: 小明, age: 18} # 方式二dict()构造函数 user2 dict(name小红, age20) # 方式三通过列表生成 user3 dict([(name, 小刚), (age, 22)]) # 空字典 empty_dict {}1.2 字典的关键约束使用字典时有两个核心规则必须牢记约束说明键必须唯一如果同一个键被赋值两次后面的值会覆盖前面的值键必须不可变键只能是字符串、数字、元组等不可变类型列表、字典、集合不能作为键python# 合法的键 d { 1: 数字键, name: 字符串键, (1, 2): 元组键 # 元组不可变OK } # 非法的键会报错 TypeError d {[1, 2]: 列表键} # 列表可变不能作为键二、字典的核心操作增删改查这是日常开发中使用频率最高的部分务必熟练掌握。2.1 查访问元素pythonuser {name: 小明, age: 18} # 方法1直接通过key访问key不存在时会报错 KeyError print(user[name]) # 输出: 小明 # print(user[sex]) # 报错 # 方法2使用get()方法推荐安全 print(user.get(sex)) # 输出: None print(user.get(sex, 未知)) # 输出: 未知可指定默认值 # 方法3setdefault()如果key不存在则设置默认值并返回 age user.setdefault(age, 0) # 存在返回18 sex user.setdefault(sex, 男) # 不存在添加 sex男返回男 print(user) # {name: 小明, age: 18, sex: 男}2.2 增 / 改添加或修改元素pythonuser {name: 小明} # 直接赋值key存在则修改不存在则新增 user[age] 18 # 新增 user[name] 大明 # 修改 print(user) # {name: 大明, age: 18} # 批量更新使用update()合并另一个字典 user.update({city: 北京, age: 19}) print(user) # {name: 大明, age: 19, city: 北京}2.3 删删除元素pythonuser {name: 小明, age: 18, city: 北京} # pop(key)删除指定key并返回对应的值 age user.pop(age) print(age) # 18 print(user) # {name: 小明, city: 北京} # popitem()删除并返回最后一个键值对Python3.7 有序 item user.popitem() print(item) # (city, 北京) print(user) # {name: 小明} # del删除指定key del user[name] print(user) # {} # clear()清空字典 user.clear() print(user) # {}三、字典的遍历技巧pythonuser {name: 小明, age: 18, city: 北京} # 1. 遍历所有key默认 for key in user: print(key, user[key]) # 2. 遍历所有key更明确 for key in user.keys(): print(key) # 3. 遍历所有value for value in user.values(): print(value) # 4. 遍历所有键值对最常用效率高 for key, value in user.items(): print(f{key}: {value})四、字典与列表的性能对比重要很多初学者在处理数据时习惯用列表但在数据量较大时列表的查找效率远低于字典。场景列表List字典Dict查找元素O(n) — 需要逐个遍历O(1)— 直接通过哈希计算位置插入元素O(1) 或 O(n)插入中间位置O(1)删除元素O(n)O(1)适用场景有序数据、栈、队列快速查找、映射关系、缓存实际案例假设有一个包含100万条数据的列表要查找某个元素是否存在最坏情况下需要遍历100万次。而使用字典只需要一次哈希计算速度是天壤之别。pythonimport time # 列表查找 lst list(range(1000000)) start time.time() print(999999 in lst) # True print(列表查找耗时:, time.time() - start) # 字典查找key就是数字本身 d {i: i for i in range(1000000)} start time.time() print(999999 in d) # True print(字典查找耗时:, time.time() - start)运行结果会让你直观感受到字典的速度优势。五、进阶技巧实用干货5.1 字典推导式类似列表推导式可以快速生成字典。python# 生成平方数字典 squares {x: x**2 for x in range(5)} print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} # 过滤只保留偶数 even_squares {x: x**2 for x in range(10) if x % 2 0} print(even_squares) # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}5.2 defaultdict —— 避免KeyError的利器当你需要统计频次或分组时defaultdict可以省去判断key是否存在的麻烦。pythonfrom collections import defaultdict # 普通方式需要判断 words [apple, banana, apple, orange, banana, apple] count {} for word in words: if word in count: count[word] 1 else: count[word] 1 # 使用defaultdict自动初始化 count defaultdict(int) # 默认值为0 for word in words: count[word] 1 print(dict(count)) # {apple: 3, banana: 2, orange: 1}5.3 Counter —— 计数专用如果只是做计数collections.Counter更加方便。pythonfrom collections import Counter words [apple, banana, apple, orange, banana, apple] count Counter(words) print(count) # Counter({apple: 3, banana: 2, orange: 1}) print(count[apple]) # 35.4 合并字典的几种方式pythond1 {a: 1, b: 2} d2 {b: 3, c: 4} # Python 3.9 使用 | 操作符 d3 d1 | d2 print(d3) # {a: 1, b: 3, c: 4} # 使用 ** 解包通用 d4 {**d1, **d2} print(d4) # {a: 1, b: 3, c: 4} # 使用 update()会修改原字典 d1.update(d2) print(d1) # {a: 1, b: 3, c: 4}六、底层原理哈希表与散列冲突字典之所以这么快底层依靠的是哈希表Hash Table。工作流程当你存储一个键值对时Python会计算键的哈希值通过hash()函数。根据哈希值计算出该键值对在内存数组中的存储位置索引。当你要查找一个键时同样计算哈希值然后直接跳转到对应位置读取数据一步到位。关于哈希冲突不同的键有可能计算出相同的哈希值或映射到同一个位置这称为“哈希冲突”。Python采用开放寻址法来解决冲突——如果发现目标位置已被占用就会继续向下探测直到找到一个空位。为什么键必须是不可变类型因为如果键是可变的比如列表其内容一旦变化哈希值就会改变导致无法再找到之前存储的数据。所以Python强制要求键必须是不可变类型。七、常见“坑”与避坑指南坑1遍历时修改字典pythond {a: 1, b: 2, c: 3} # 错误在遍历过程中删除元素会报错 for key in d: if key b: del d[key] # RuntimeError: dictionary changed size during iteration # 正确方式先转为列表再遍历 for key in list(d.keys()): if key b: del d[key] print(d) # {a: 1, c: 3}坑2用列表作为键python# 错误示例 d {[1, 2]: value} # TypeError: unhashable type: list # 如果需要用序列作为键请用元组 d {(1, 2): value} # OK坑3复制字典时引用同一个对象pythond1 {a: [1, 2]} d2 d1 # 浅复制d2和d1指向同一个对象 d2[a].append(3) print(d1) # {a: [1, 2, 3]} —— 原字典被修改了 # 正确方式深拷贝 import copy d1 {a: [1, 2]} d2 copy.deepcopy(d1) d2[a].append(3) print(d1) # {a: [1, 2]} —— 原字典不变八、总结知识点要点核心特性键值对存储、键唯一且不可变、无序Python3.7 插入有序访问方式优先使用get()避免KeyError遍历items()遍历键值对效率最高性能查找/插入/删除都是O(1)远优于列表底层基于哈希表实现键必须可哈希推荐库defaultdict、Counter简化代码字典是Python开发中不可或缺的利器掌握它能让你的代码更加优雅、高效。希望这篇文章能帮你系统地梳理字典的知识点也欢迎在评论区交流你的使用心得如果觉得这篇文章对你有帮助记得点赞、收藏、关注三连支持一下 你的鼓励是我持续输出的动力本文为原创首发于CSDN转载请注明出处。
Python字典,核心编程必备技能,建议收藏!
Python字典核心编程必备技能建议收藏前言大家好我是[你的名字]。在日常Python开发中字典dict绝对是我用得最频繁的数据结构没有之一。无论是处理JSON数据、缓存配置还是做计数器、去重字典都扮演着至关重要的角色。今天这篇文章我想把自己对字典的理解系统性地整理出来从基础用法到底层原理再到一些容易被忽视的“坑”希望能帮你彻底掌握Python字典。话不多说我们直接开始。一、什么是字典字典是Python内置的一种可变、无序的容器模型以“键值对”key: value的形式存储数据。你可以把它想象成一个现实中的电话本通过人名键就能快速找到电话号码值而不需要从头翻到尾。1.1 字典的创建方式python# 方式一花括号最常用 user {name: 小明, age: 18} # 方式二dict()构造函数 user2 dict(name小红, age20) # 方式三通过列表生成 user3 dict([(name, 小刚), (age, 22)]) # 空字典 empty_dict {}1.2 字典的关键约束使用字典时有两个核心规则必须牢记约束说明键必须唯一如果同一个键被赋值两次后面的值会覆盖前面的值键必须不可变键只能是字符串、数字、元组等不可变类型列表、字典、集合不能作为键python# 合法的键 d { 1: 数字键, name: 字符串键, (1, 2): 元组键 # 元组不可变OK } # 非法的键会报错 TypeError d {[1, 2]: 列表键} # 列表可变不能作为键二、字典的核心操作增删改查这是日常开发中使用频率最高的部分务必熟练掌握。2.1 查访问元素pythonuser {name: 小明, age: 18} # 方法1直接通过key访问key不存在时会报错 KeyError print(user[name]) # 输出: 小明 # print(user[sex]) # 报错 # 方法2使用get()方法推荐安全 print(user.get(sex)) # 输出: None print(user.get(sex, 未知)) # 输出: 未知可指定默认值 # 方法3setdefault()如果key不存在则设置默认值并返回 age user.setdefault(age, 0) # 存在返回18 sex user.setdefault(sex, 男) # 不存在添加 sex男返回男 print(user) # {name: 小明, age: 18, sex: 男}2.2 增 / 改添加或修改元素pythonuser {name: 小明} # 直接赋值key存在则修改不存在则新增 user[age] 18 # 新增 user[name] 大明 # 修改 print(user) # {name: 大明, age: 18} # 批量更新使用update()合并另一个字典 user.update({city: 北京, age: 19}) print(user) # {name: 大明, age: 19, city: 北京}2.3 删删除元素pythonuser {name: 小明, age: 18, city: 北京} # pop(key)删除指定key并返回对应的值 age user.pop(age) print(age) # 18 print(user) # {name: 小明, city: 北京} # popitem()删除并返回最后一个键值对Python3.7 有序 item user.popitem() print(item) # (city, 北京) print(user) # {name: 小明} # del删除指定key del user[name] print(user) # {} # clear()清空字典 user.clear() print(user) # {}三、字典的遍历技巧pythonuser {name: 小明, age: 18, city: 北京} # 1. 遍历所有key默认 for key in user: print(key, user[key]) # 2. 遍历所有key更明确 for key in user.keys(): print(key) # 3. 遍历所有value for value in user.values(): print(value) # 4. 遍历所有键值对最常用效率高 for key, value in user.items(): print(f{key}: {value})四、字典与列表的性能对比重要很多初学者在处理数据时习惯用列表但在数据量较大时列表的查找效率远低于字典。场景列表List字典Dict查找元素O(n) — 需要逐个遍历O(1)— 直接通过哈希计算位置插入元素O(1) 或 O(n)插入中间位置O(1)删除元素O(n)O(1)适用场景有序数据、栈、队列快速查找、映射关系、缓存实际案例假设有一个包含100万条数据的列表要查找某个元素是否存在最坏情况下需要遍历100万次。而使用字典只需要一次哈希计算速度是天壤之别。pythonimport time # 列表查找 lst list(range(1000000)) start time.time() print(999999 in lst) # True print(列表查找耗时:, time.time() - start) # 字典查找key就是数字本身 d {i: i for i in range(1000000)} start time.time() print(999999 in d) # True print(字典查找耗时:, time.time() - start)运行结果会让你直观感受到字典的速度优势。五、进阶技巧实用干货5.1 字典推导式类似列表推导式可以快速生成字典。python# 生成平方数字典 squares {x: x**2 for x in range(5)} print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} # 过滤只保留偶数 even_squares {x: x**2 for x in range(10) if x % 2 0} print(even_squares) # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}5.2 defaultdict —— 避免KeyError的利器当你需要统计频次或分组时defaultdict可以省去判断key是否存在的麻烦。pythonfrom collections import defaultdict # 普通方式需要判断 words [apple, banana, apple, orange, banana, apple] count {} for word in words: if word in count: count[word] 1 else: count[word] 1 # 使用defaultdict自动初始化 count defaultdict(int) # 默认值为0 for word in words: count[word] 1 print(dict(count)) # {apple: 3, banana: 2, orange: 1}5.3 Counter —— 计数专用如果只是做计数collections.Counter更加方便。pythonfrom collections import Counter words [apple, banana, apple, orange, banana, apple] count Counter(words) print(count) # Counter({apple: 3, banana: 2, orange: 1}) print(count[apple]) # 35.4 合并字典的几种方式pythond1 {a: 1, b: 2} d2 {b: 3, c: 4} # Python 3.9 使用 | 操作符 d3 d1 | d2 print(d3) # {a: 1, b: 3, c: 4} # 使用 ** 解包通用 d4 {**d1, **d2} print(d4) # {a: 1, b: 3, c: 4} # 使用 update()会修改原字典 d1.update(d2) print(d1) # {a: 1, b: 3, c: 4}六、底层原理哈希表与散列冲突字典之所以这么快底层依靠的是哈希表Hash Table。工作流程当你存储一个键值对时Python会计算键的哈希值通过hash()函数。根据哈希值计算出该键值对在内存数组中的存储位置索引。当你要查找一个键时同样计算哈希值然后直接跳转到对应位置读取数据一步到位。关于哈希冲突不同的键有可能计算出相同的哈希值或映射到同一个位置这称为“哈希冲突”。Python采用开放寻址法来解决冲突——如果发现目标位置已被占用就会继续向下探测直到找到一个空位。为什么键必须是不可变类型因为如果键是可变的比如列表其内容一旦变化哈希值就会改变导致无法再找到之前存储的数据。所以Python强制要求键必须是不可变类型。七、常见“坑”与避坑指南坑1遍历时修改字典pythond {a: 1, b: 2, c: 3} # 错误在遍历过程中删除元素会报错 for key in d: if key b: del d[key] # RuntimeError: dictionary changed size during iteration # 正确方式先转为列表再遍历 for key in list(d.keys()): if key b: del d[key] print(d) # {a: 1, c: 3}坑2用列表作为键python# 错误示例 d {[1, 2]: value} # TypeError: unhashable type: list # 如果需要用序列作为键请用元组 d {(1, 2): value} # OK坑3复制字典时引用同一个对象pythond1 {a: [1, 2]} d2 d1 # 浅复制d2和d1指向同一个对象 d2[a].append(3) print(d1) # {a: [1, 2, 3]} —— 原字典被修改了 # 正确方式深拷贝 import copy d1 {a: [1, 2]} d2 copy.deepcopy(d1) d2[a].append(3) print(d1) # {a: [1, 2]} —— 原字典不变八、总结知识点要点核心特性键值对存储、键唯一且不可变、无序Python3.7 插入有序访问方式优先使用get()避免KeyError遍历items()遍历键值对效率最高性能查找/插入/删除都是O(1)远优于列表底层基于哈希表实现键必须可哈希推荐库defaultdict、Counter简化代码字典是Python开发中不可或缺的利器掌握它能让你的代码更加优雅、高效。希望这篇文章能帮你系统地梳理字典的知识点也欢迎在评论区交流你的使用心得如果觉得这篇文章对你有帮助记得点赞、收藏、关注三连支持一下 你的鼓励是我持续输出的动力本文为原创首发于CSDN转载请注明出处。