一、增(Add / Update)
1.1 下标赋值 & 新增键
脚本:01_setitem.py
d = {"a": 1}
d["b"] = 2 # 键不存在则新增
d["a"] = 99 # 键存在则覆盖
print("after:", d) # {'a': 99, 'b': 2}
1.2 update() —— 批量更新/新增
脚本:02_update.py
d = {"a": 1}
d.update({"b": 2, "c": 3}) # 字典
d.update([("d", 4), ("e", 5)]) # 可迭代键值对
print("update:", d) # {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
# 合并运算符 | (3.9+)
new_d = d | {"f": 6}
print("d | {...}:", new_d) # 原字典不变
1.3 setdefault() —— “获取 or 插入”
脚本:03_setdefault.py
d = {"a": 1}
val = d.setdefault("a", 99) # 键存在,返回原值
print("setdefault exist:", val, d) # 1 {'a': 1}
val2 = d.setdefault("b", 2) # 键不存在,插入并返回默认值
print("setdefault new:", val2, d) # 2 {'a': 1, 'b': 2}
用途:计数器/分组时避免if key in d:判断。
二、删(Remove / Pop / Clear)
2.1 pop(key[, default]) —— 按键删除并返回值
脚本:04_pop.py
d = {"a": 1, "b": 2}
val = d.pop("a") # 删除并返回 1
print("pop:", val, d) # 1 {'b': 2}
# 键不存在 + 无 default KeyError
missing = d.pop("z", None) # 提供默认值避免异常
print("pop default:", missing, d) # None {'b': 2}
2.2 popitem() —— LIFO 弹出(3.7+ 保序)
脚本:05_popitem.py
d = {"x": 10, "y": 20, "z": 30}
while d:
k, v = d.popitem()
print(f"popitem: {k}={v}")
2.3 del 语句 —— 按键删除
脚本:06_del.py
d = {"a": 1, "b": 2}
del d["a"]
print("after del:", d) # {'b': 2}
# del d["z"] # KeyError
2.4 clear() —— 清空字典
脚本:07_clear.py
d = {"a": 1, "b": 2}
d.clear()
print("cleared:", d, len(d)) # {} 0
三、查(Get / Keys / Values / Items)
3.1 get(key[, default]) —— 安全取值
脚本:08_get.py
d = {"a": 1}
val = d.get("a") # 存在返回 1
missing = d.get("z", 0) # 不存在返回默认值 0
print("get:", val, missing)
# 对比 d["z"] 抛 KeyError
3.2 keys() / values() / items() —— 视图对象
脚本:09_views.py
d = {"name": "Bob", "age": 20}
ks = d.keys(); vs = d.values(); its = d.items()
print("keys:", list(ks))
print("items:", list(its))
# 视图动态反映原字典变化
d["city"] = "NY"
print("after add:", list(ks)) # 视图自动更新
3.3 成员运算符 in / not in
脚本:10_member.py
d = {"a": 1, "b": 2}
print("'a' in d:", "a" in d) # True(判断键)
print("1 in d.values():", 1 in d.values()) # True
四、排序与比较
4.1 按键排序 —— sorted + key
脚本:11_sort_keys.py
d = {"b": 2, "a": 1, "c": 3}
asc_keys = sorted(d) # 仅对键排序
print("sorted keys:", asc_keys) # ['a', 'b', 'c']
# 按键排序返回列表 of 键值对
sorted_items = sorted(d.items(), key=lambda kv: kv[0])
print("sorted items by key:", sorted_items) # [('a', 1), ('b', 2), ('c', 3)]
4.2 按值排序
脚本:12_sort_values.py
d = {"apple": 3, "banana": 1, "cherry": 2}
by_value = sorted(d.items(), key=lambda kv: kv[1])
print("by value asc:", by_value) # [('banana', 1), ('cherry', 2), ('apple', 3)]
# 降序
by_value_desc = sorted(d.items(), key=lambda kv: kv[1], reverse=True)
print("by value desc:", by_value_desc)
五、复制与深拷贝
5.1 浅拷贝 —— copy()
脚本:13_shallow_copy.py
import copy
d1 = {"a": [1, 2], "b": 3}
d2 = d1.copy() # 或 d2 = dict(d1)
d2["a"].append(99); d2["b"] = 4
print("d1:", d1) # {'a': [1, 2, 99], 'b': 3} 子对象共享
print("d2:", d2) # {'a': [1, 2, 99], 'b': 4}
5.2 深拷贝 —— copy.deepcopy()
脚本:14_deep_copy.py
import copy
d1 = {"a": [1, 2], "b": 3}
d2 = copy.deepcopy(d1)
d2["a"].append(99)
print("d1:", d1) # {'a': [1, 2], 'b': 3} 完全独立
print("d2:", d2) # {'a': [1, 2, 99], 'b': 3}
六、合并与运算(3.9+ 运算符)
6.1 | 合并(新建)
脚本:15_union_operator.py
d1 = {"a": 1, "b": 2}
d2 = {"b": 3, "c": 4}
merged = d1 | d2 # 键冲突取后者
print("d1 | d2:", merged) # {'a': 1, 'b': 3, 'c': 4}
print("原 d1:", d1) # 不变
6.2 |= 就地合并
脚本:16_ior_operator.py
d1 = {"a": 1, "b": 2}
d1 |= {"b": 3, "c": 4}
print("d1 |= :", d1) # {'a': 1, 'b': 3, 'c': 4} 就地
七、特殊用途方法
7.1 fromkeys() —— 批量设相同值
脚本:17_fromkeys.py
keys = ["a", "b", "c"]
d = dict.fromkeys(keys, 0) # 所有值共享 0
print("fromkeys:", d) # {'a': 0, 'b': 0, 'c': 0}
# 注意:可变对象共享引用
d2 = dict.fromkeys(keys, [])
d2["a"].append(1)
print("共享可变值:", d2) # {'a': [1], 'b': [1], 'c': [1]}
# 正确:推导式
d3 = {k: [] for k in keys}
7.2 setdefault 链式分组
脚本:18_group_by.py
words = ["apple", "banana", "apricot", "cherry"]
groups = {}
for w in words:
groups.setdefault(w[0], []).append(w) # 首字母分组
print("group by 1st letter:", groups)
# 等效 defaultdict(list) 但更通用
八、性能与内存
8.1 成员测试速度
脚本:19_member_speed.py
import timeit, random
n = 100000; d = {i: i for i in range(n)}; target = random.randint(0, n-1)
t_dict = timeit.timeit('target in d', globals=globals(), number=100000)
lst = list(d); t_list = timeit.timeit('target in lst', globals=globals(), number=100000)
print("dict member:", t_dict, "list member:", t_list)
结论:哈希表 O(1) 平均;列表 O(n)。
8.2 内存占用对比
脚本:20_memory.py
import sys, random, string
n = 100000; keys = [''.join(random.choices(string.ascii_letters, k=8)) for _ in range(n)]
lst = keys[:] # 列表只存引用
d = dict.fromkeys(keys, 0)
print("list mem:", sys.getsizeof(lst), "bytes")
print("dict mem:", sys.getsizeof(d), "bytes") # 哈希表额外开销
九、实用技巧 & 综合案例
9.1 字典转 DataFrame
脚本:21_dict_to_df.py
import pandas as pd
data = {"name": ["Alice", "Bob"], "age": [25, 30]}
df = pd.DataFrame(data)
print(df)
9.2 嵌套字典默认值(递归 defaultdict)
脚本:22_nested_defaultdict.py
from collections import defaultdict
def tree(): return defaultdict(tree)
root = tree()
root["a"]["b"]["c"] = 1
print("nested:", root)
9.3 字典合并成 URL 查询串
params = {"q": "python", "page": 2}
query = "&".join(f"{k}={v}" for k, v in params.items())
print("query:", query) # q=python&page=2