Python字典对象提供一组方法,专门处理取值、合并、删除和复制,以及取出键、值、键值对的视图。和列表方法类似,有的只查询,有的会改原字典。按使用频率把常用接口拆开说明,对着代码看行为即可。

keys、values、items

三个方法分别给出键、值、以及 (键, 值) 对。返回的是视图:字典后来又改了,视图里看到的内容也会跟着变,并不是改动发生那一刻的静态拷贝:

d = {"a": 1, "b": 2}
print(d.keys())      # dict_keys(['a', 'b'])
print(d.values())    # dict_values([1, 2])
print(d.items())     # dict_items([('a', 1), ('b', 2)])

视图本身不能按下标取第几个键。需要下标、切片,或要交给只吃列表的接口时,再包一层 list(...)

print(list(d.keys()))      # ['a', 'b']
print(list(d.items()))     # [('a', 1), ('b', 2)]

get:安全取值

键确定存在时,方括号和 get 都能取到值。差别出在键缺失:方括号抛 KeyErrorget 返回 None,或你传入的第二个参数。读配置、读可选字段时,用 get 可以少写一层判断:

d = {"a": 1}
print(d.get("a"))          # 1
print(d.get("x"))          # None
print(d.get("x", 0))       # 0

update:合并字典

update 把另一个字典里的键值写进当前字典。遇上同名键,以传入的那边为准,原字典被就地修改。若只想得到合并结果、又不想动原来的两个字典,Python 3.9 起可以用 | 生成新字典:

a = {"x": 1, "y": 2}
b = {"y": 100, "z": 3}
a.update(b)
print(a)                   # {'x': 1, 'y': 100, 'z': 3}

# Python 3.9+
# merged = {"x": 1, "y": 2} | {"y": 100, "z": 3}

setdefault:有则取、无则设

调用 setdefault(key, default) 时,键已在字典里就直接返回原值。不在,则先把 default 写进去再返回。它和先 get 到缺省再手动赋值经常一起出现在计数、按键归类的代码里。下面两种计数写法结果相同,第二种把没有就先铺 0 收进了 setdefault

counts = {}
for word in ["apple", "banana", "apple"]:
    counts[word] = counts.get(word, 0) + 1
print(counts)              # {'apple': 2, 'banana': 1}

counts2 = {}
for word in ["a", "b", "a"]:
    counts2.setdefault(word, 0)
    counts2[word] += 1
print(counts2)             # {'a': 2, 'b': 1}

往嵌套字典里塞列表或子字典时,也可以 setdefault(key, []) / setdefault(key, {}),避免先判断键是否存在再创建容器。

pop、popitem、clear

pop(key) 删除指定键并返回它的值,可加缺省参数以免键不存在时抛错。popitem 不接收键名,按最后插入的那一项删除并返回键值对(3.7 起字典保序)。clear 清空所有条目,字典对象还在,只是变成空的:

d = {"a": 1, "b": 2, "c": 3}
print(d.pop("a"))          # 1
print(d)                   # {'b': 2, 'c': 3}

print(d.popitem())         # ('c', 3)
print(d)                   # {'b': 2}

d.clear()
print(d)                   # {}

copy:复制字典

b = a 只会多一个名字指向同一份字典,改 b 就是改 acopy() 做浅拷贝,最外层的键值分开了,但值如果是列表、字典,两边仍共享同一个内部对象。只要改的是顶层键的指向(例如 b["y"] = 2),原字典不受影响:

a = {"x": 1}
b = a.copy()
b["y"] = 2
print(a, b)                # {'x': 1} {'x': 1, 'y': 2}

若值里还有可变对象,又需要完全断开,要用 copy.deepcopy,那是标准库 copy 模块的事,和字典自己的 copy() 不是同一层。

常用方法总表

方法作用
keys() / values() / items()键 / 值 / 键值对视图
get(key, default)安全取值,避免 KeyError
update(other)合并进当前字典,同键覆盖
setdefault(key, default)有则取、无则写入缺省
popkey, default)删除并返回,可带缺省
popitem()删除并返回最后一项
clear()清空
copy()浅拷贝

实际项目里,读可选字段用 get,合并配置用 update|,按键累计用 setdefaultget,遍历键值用 items,这几项覆盖了大部分日常写法。