
前言字典dict提供了一批内置方法名字都短但行为差别不小get和setdefault都能「给个默认值」可一个只读不写、一个会写回去pop和popitem都删东西但一个删你指定的键、一个删末尾keys/values/items返回的是视图而不是列表。这些差别如果只靠猜很容易写出「看起来对、跑起来错」的代码。本文不铺陈概念直接一个方法一个方法地过给出它的签名形参怎么传、/前后是位置还是关键字、有没有默认值再说明它返回什么、是原地修改还是返回新对象。所有签名以 Python 官方文档为准示例可在 Python 3.8 及以上运行个别方法标注了更高的版本要求。逐个方法讲完最后一节用表格汇总并列出常见坑点。一、读值get(key, defaultNone, /)get返回键对应的值键不存在时返回defaultdefault省略则为None。它从不抛KeyError也从不修改字典。# 适用于 Python 3.8d {a: 1, b: 2}print(d.get(a)) # 1print(d.get(z)) # Noneprint(d.get(z, 0)) # 0print(d) # {a: 1, b: 2}字典没变注意签名里的/d.get(z, 0)这样按位置传没问题但d.get(keyz)会报TypeError因为这两个参数都是仅位置参数。二、缺键才写setdefault(key, defaultNone, /)setdefault是get的「带写入」版本键在返回值键不在先插入key: default再返回default。# 适用于 Python 3.8d {a: 1}print(d.setdefault(a, 99)) # 1已存在就不覆盖print(d.setdefault(b, 2)) # 2不存在则写入print(d) # {a: 1, b: 2}s这个语义让它成为「分组建桶」的利器后面在实战篇里会用到。它的默认值同样是None。三、批量更新update(...)update有几种调用形式update(mapping, /, **kwargs)、update(iterable, /, **kwargs)、update(**kwargs)。它原地把另一个映射或键值对序列合并进来覆盖已有键返回None。# 适用于 Python 3.8d {a: 1}d.update({b: 2, a: 100}) # 传映射d.update([(c, 3)]) # 传键值对序列d.update(d4) # 传关键字参数print(d) # {a: 100, b: 2, c: 3, d: 4}update返回None是常见误解点它不返回新字典。四、删除pop(key, /)与popitem()pop(key, /)删除指定键并返回其值键不存在且没给默认值就抛KeyError给了默认值d.pop(key, default)则返回默认值。# 适用于 Python 3.8d {a: 1, b: 2}print(d.pop(a)) # 1print(d.pop(z, None)) # Noneprint(d) # {b: 2}popitem()不接受参数删除并返回最后一个键值对从 Python 3.7 起保证是 LIFO后进先出。空字典上调用会抛KeyError。# 适用于 Python 3.8d {a: 1, b: 2, c: 3}print(d.popitem()) # (c, 3)最后插入的先出print(d.popitem()) # (b, 2)五、清空与拷贝clear()和copy()clear()删除全部项返回None。copy()返回一个浅拷贝新字典是新的对象但里面嵌套的可变值仍与原字典共享。# 适用于 Python 3.8d {a: 1, b: {n: 1}}e d.copy()e[a] 99 # 顶层互不影响e[b][n] 88 # ❗ 内层还是同一个对象print(d) # {a: 1, b: {n: 88}}d.clear()print(d) # {}六、三个视图keys()、values()、items()三者都返回视图对象动态反映字典变化支持len()和in。keys()的返回项是键values()是值items()是(key, value)元组。键视图和项视图还支持集合运算。# 适用于 Python 3.8d {a: 1, b: 2}print(list(d.keys())) # [a, b]print(list(d.values())) # [1, 2]print(list(d.items())) # [(a, 1), (b, 2)]print(d.keys() {b, c}) # {b}键视图可做交集有一个反直觉的事实d.values()之间比较永远为False即使内容一样因为值视图不保证唯一、不被当作集合。# 适用于 Python 3.8d {a: 1}print(d.values() d.values()) # False七、从序列造字典fromkeys(iterable, valueNone, /)fromkeys是类方法返回一个新字典键来自iterable所有键共用同一个value。# 适用于 Python 3.8keys [a, b, c]d dict.fromkeys(keys)print(d) # {a: None, b: None, c: None}d2 dict.fromkeys(keys, 0)print(d2) # {a: 0, b: 0, c: 0}关键陷阱在下一节第一条如果value是可变对象比如空列表所有键会共享同一个列表。八、合并|与|Python 3.9d | other返回新字典d | other原地更新两者都是other的值优先。这与集合的|并集语义不同别混。# 适用于 Python 3.9a {x: 1, y: 2}b {y: 20, z: 30}print(a | b) # {x: 1, y: 20, z: 30}a 未被改动a | bprint(a) # {x: 1, y: 20, z: 30}a 被改动Python 3.9 之前等价写法是{**a, **b}新字典和a.update(b)原地。常见坑点坑一用可变对象做fromkeys的值。# 适用于 Python 3.8# ❌ 三个键共享同一个列表d dict.fromkeys([a, b, c], [])d[a].append(1)print(d) # {a: [1], b: [1], c: [1]}# ✅ 用字典推导式每个键各建一个d {k: [] for k in [a, b, c]}d[a].append(1)print(d) # {a: [1], b: [], c: []}坑二把setdefault当纯读取用。# 适用于 Python 3.8# ❌ 只想读却顺手写进了一个键d {a: 1}d.setdefault(b) # 返回 None同时 d 变成 {a: 1, b: None}# ✅ 只读用 getd.get(b) # 仅返回 None不写坑三以为pop(k, v)的第二个参数是「默认保留值」。# 适用于 Python 3.8# ❌ 它不是「取不到就用这个值代替原值」而是「取不到就返回它」d {a: 1}print(d.pop(a, 0)) # 1能取到就返回真值print(d.pop(a, 0)) # 0已删掉返回默认值# ✅ 想「有就删、没有忽略」就显式传默认值d.pop(z, None)坑四对空字典调用popitem()。# 适用于 Python 3.8# ❌ 空字典上 popitem 抛 KeyErrord {}d.popitem() # KeyError: popitem(): dictionary is empty# ✅ 先判空或用 pop 给默认值if d:d.popitem()d.pop(missing, None)坑五以为values()能直接比大小。# 适用于 Python 3.8# ❌ 值视图之间永远不等d {a: 1}print(d.values() d.values()) # False# ✅ 转成 list 再比print(list(d.values()) list(d.values())) # True坑六copy()之后修改嵌套结构。# 适用于 Python 3.8# ❌ 浅拷贝只到第一层d {cfg: {verbose: False}}e d.copy()e[cfg][verbose] Trueprint(d[cfg][verbose]) # True原字典也变了# ✅ 要彻底隔离用 deepcopyimport copye copy.deepcopy(d)坑七在 3.9 以前用|合并字典。# 适用于 Python 3.9# ❌ 3.8 及更早版本没有字典的 | 运算符这行会抛 TypeError# d {a: 1} | {b: 2}# ✅ 3.9 可以直接用 |需要在旧版本跑就改用 {**a, **b}d {**{a: 1}, **{b: 2}}print(d) # {a: 1, b: 2}总结方法返回是否改原字典要点get(k, dNone)值或默认否从不抛KeyErrorsetdefault(k, dNone)值或默认缺键时写会插入update(...)None是覆盖已有键pop(k[, d])被删的值是缺键可给默认popitem()(k, v)是3.7 起 LIFOclear()None是清空copy()新字典否浅拷贝keys/values/items()视图否动态、可迭代fromkeys(seq, v)新字典否可变值会共享\/\新字典 /None记牢三组对比就不容易出错get不写、setdefault会写pop删指定键、popitem删末尾|出新字典、|改原字典。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。