字典(dict)是 Python 中使用频率最高的数据结构之一,它以键值对(key-value pair)的形式存储数据,支持通过键快速查找对应的值。在数据处理、配置管理、缓存等场景中,字典都是首选。
底层实现:哈希表
Python 的字典底层基于哈希表(hash table)实现,核心思想是将键通过哈希函数映射到一个固定大小的数组索引上。
- 可哈希的键:只有不可变类型才能作为字典的键,常见的有字符串、数字、元组(元组内的元素也必须可哈希)。列表、集合等可变类型不能作为键,因为它们的内容可变化,哈希值也会跟着变,无法稳定定位。
- 哈希冲突:不同键可能计算出相同的哈希索引,Python 内部使用开放寻址法(open addressing)来解决冲突,保证查找的正确性。
- 时间复杂度:理想情况下,增、删、改、查的平均时间复杂度都是 O(1)。随着字典中元素增加,Python 会自动扩容并重新散列,以保证效率。在实际使用中,字典的查找极快,除非刻意制造大量哈希冲突。
简单说,字典就是一个通过哈希表实现的“快速查找映射表”,给了我们用键瞬间取值的便利。
常用方法
字典提供了一套直观的方法来操作数据,下面是最常用的几个:
d = {'name': 'Alice', 'age': 25, 'city': 'Beijing'}
- 获取所有键 / 值 / 键值对
d.keys()→ 返回所有键的视图,可遍历。d.values()→ 返回所有值的视图。d.items()→ 返回 (key, value) 元组的视图,遍历字典时最常用。- 安全取值
d.get('name')→ 返回'Alice',键不存在时返回None,不会报错。d.get('gender', 'N/A')→ 键不存在时返回默认值'N/A',实用性极高。- 设置默认值
d.setdefault('country', 'China')→ 如果'country'不存在,则添加进去并返回设置的值;如果已存在,直接返回现有值。常用于累加型场景,比如单词计数时避免 KeyError。- 删除元素
d.pop('age')→ 删除并返回'age'对应的值,键不存在会报错。d.pop('gender', None)→ 键不存在时返回默认值,优雅处理。del d['city']→ 直接删除键值对,键不存在会报错。- 更新与合并
d.update({'age': 26, 'job': 'Engineer'})→ 批量更新或新增键值对。- Python 3.9+ 支持
|运算符合并字典:new_dict = d1 | d2,返回一个新字典,有重复键时右边覆盖左边。
字典推导式
字典推导式提供了一种从可迭代对象高效构建字典的写法,语法类似列表推导,因为使用 : 分隔键和值。
# 从列表构造映射:数字 → 它的平方
squares = {x: x**2 for x in range(5)}
# 结果:{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# 反转键值对(值需唯一)
reversed = {v: k for k, v in d.items()}
# 带条件过滤
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
对于简单的字典生成场景,推导式比循环 + 逐个赋值更加清晰且执行速度更快。
有序性特性
从 Python 3.7 开始,字典的插入顺序被正式保留(CPython 3.6 已实现,3.7 成为语言规范)。这意味着遍历字典时,键值对会按照它们被添加的顺序出现。
d = {}
d['a'] = 1
d['b'] = 2
d['c'] = 3
print(list(d.keys())) # ['a', 'b', 'c'],严格按插入顺序
这个特性让字典在实际使用中更加直观,例如:
- 记录用户登录顺序、配置加载顺序。
- 配合
json.dumps输出 JSON 时,字段顺序与定义顺序一致。 - 可以用字典替代
OrderedDict的大部分场景。
注意:虽然字典有序,但比较两个字典时,Python 会忽略顺序,只检查键值对是否相同。此外,若想在 Python 3.6 及更早版本保证顺序,仍需使用 collections.OrderedDict。