字典基础
字典(dict)是 Python 中最强大的数据结构之一。它存储键值对(key-value pairs),通过键来快速查找值。字典是无序的(Python 2.7 中)、可变的,键必须唯一且可哈希。
创建字典
# 空字典
empty = {}
empty = dict()
# 字面量
person = {"name": "Alice", "age": 25, "city": "Beijing"}
# 从键值对序列创建
pairs = [("a", 1), ("b", 2), ("c", 3)]
d = dict(pairs)
print d # {'a': 1, 'c': 3, 'b': 2}
# 用关键字参数(键必须是合法标识符)
d = dict(name="Bob", age=30)
print d # {'age': 30, 'name': 'Bob'}
访问与修改
d = {"name": "Alice", "age": 25}
# 访问
print d["name"] # "Alice"
print d["age"] # 25
# 键不存在时抛出 KeyError
print d["gender"] # KeyError: 'gender'
# 安全访问:用 get()
print d.get("gender") # None,不报错
print d.get("gender", "unknown") # "unknown",提供默认值
# 修改
d["age"] = 26
print d # {'age': 26, 'name': 'Alice'}
# 添加新键
d["gender"] = "female"
print d # {'age': 26, 'name': 'Alice', 'gender': 'female'}
键的限制
字典的键必须是不可变(可哈希)的对象:
# 合法键
d = {
"string": 1, # str
42: 2, # int
3.14: 3, # float
(1, 2): 4, # tuple(元素也必须不可变)
True: 5, # bool
}
# 非法键
d = {
[1, 2]: "A", # TypeError: unhashable type: 'list'
{"a": 1}: "B", # TypeError: unhashable type: 'dict'
}
为什么键必须可哈希?因为字典底层使用哈希表实现。键的哈希值决定了值存储的位置,这样查找时间复杂度是 O(1)。如果键可变,哈希值会改变,导致找不到已存储的值。
键的唯一性
字典中每个键只能出现一次。重复赋值会覆盖旧值:
d = {"a": 1, "a": 2}
print d # {'a': 2},第二个覆盖了第一个
d = {}
d["x"] = 1
d["x"] = 2
print d # {'x': 2}
删除键值对
d = {"a": 1, "b": 2, "c": 3}
# del 语句
del d["a"]
print d # {'c': 3, 'b': 2}
# pop():删除并返回值
val = d.pop("b")
print val # 2
print d # {'c': 3}
# pop() 键不存在时
d.pop("z") # KeyError
d.pop("z", None) # 返回 None,不报错
# 清空
d.clear()
print d # {}
字典推导式
与列表推导式类似,字典也有推导式:
# 平方映射
squares = {x: x**2 for x in range(6)}
print squares # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# 过滤
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
print even_squares # {0: 0, 8: 64, 2: 4, 4: 16, 6: 36}
# 从两个列表创建字典
keys = ["a", "b", "c"]
values = [1, 2, 3]
d = {k: v for k, v in zip(keys, values)}
print d # {'a': 1, 'c': 3, 'b': 2}
实际应用
# 计数器
words = ["apple", "banana", "apple", "cherry", "banana", "apple"]
counts = {}
for word in words:
if word in counts:
counts[word] += 1
else:
counts[word] = 1
print counts # {'cherry': 1, 'banana': 2, 'apple': 3}
# 用 get() 简化
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
# 用 setdefault() 简化
counts = {}
for word in words:
counts.setdefault(word, 0)
counts[word] += 1
哈希冲突的说明
字典的 O(1) 查找是平均情况,最坏情况(所有键哈希冲突)是 O(n)。Python 的哈希表实现会自动扩容和重新哈希,保持较低的装载因子(通常 < 2/3),所以实际使用中几乎总是接近 O(1)。