直接赋值 dict[key] = value 是最常用方式,覆盖或新增键值对;update() 用于合并多个键值对;setdefault() 适用于“有则取、无则设”场景;key 必须为不可变类型。

直接赋值 dict[key] = value 是最常用、最直观的方式
绝大多数时候,你只是想加一个键值对,比如给 user_info 加个邮箱字段,直接写 user_info["email"] = "a@b.com" 就行。它不关心这个 key 原来存不存在——存在就覆盖,不存在就新增。
常见错误现象:KeyError 从不在这儿发生(因为不是取值),但容易误以为会报错而绕路用 setdefault() 或判断;也有人担心并发写入出问题,其实单线程下完全不用顾虑。
使用场景:初始化后补字段、循环中逐个填充、配置项动态注入。
- 如果 key 是变量,记得别漏引号:
field = "age"; user_info[field] = 25✅,user_info[field]不加引号是语法错误 ❌ - 嵌套字典要先确保上层存在,否则报
KeyError:user_info["profile"]["city"] = "Beijing"前得先有user_info["profile"] = {} - 性能上毫无压力,比
update()单次操作还快一点点,没额外函数调用开销
update() 适合一次塞多个键值对或合并另一个字典
update() 的核心价值不是“添加”,而是“合并”——它把传入的映射对象(字典、可迭代的二元组、关键字参数)里的所有键值对一股脑怼进来,已存在的 key 被覆盖,新的 key 被插入。
立即学习“Python免费学习笔记(深入)”;
常见错误现象:传了非映射对象,比如 d.update("abc") 报 ValueError: dictionary update sequence element #0 has length 1; 2 is required;或者传了列表但里面不是二元组,比如 [("a", 1), "b"] 也会崩。
使用场景:从 API 响应补全数据、合并默认配置与用户配置、批量更新缓存。
- 支持三种传参形式:
d.update(other_dict)、d.update([("k1", v1), ("k2", v2)])、d.update(k1=v1, k2=v2) - 传入字典时,原字典不会被修改;但若传入的是嵌套可变对象(比如子 dict),那深层引用仍共享 ——
update()是浅拷贝 - Python 3.9+ 可用
|运算符替代,如d = d | other,行为一致但返回新字典,不修改原d
别用 setdefault() 或 get() 来“添加”,那是它们的副作用
setdefault(key, default) 看起来像添加,实际语义是“如果 key 不存在,就设成 default 并返回 default;否则返回已有值”。它不是为添加设计的,强行用来添加容易逻辑错乱。
常见错误现象:重复调用 setdefault("items", []).append(x),第一次创建空列表并追加,第二次却在已有列表上追加——你以为每次都是新列表,其实不是。
使用场景:真正需要“有则取、无则设且返回”的分支逻辑,比如构建分组字典:groups.setdefault(category, []).append(item) 是合理用法。
- 如果只是想确保 key 存在并赋初值,又不关心返回值,直接
d[key] = d.get(key, default)更直白 -
get()本身不修改字典,纯读操作;把它和赋值混用(如d[key] = d.get(key, 0) + 1)没问题,但别指望它自动帮你“添加” - 性能上,
setdefault()比直接赋值多一次查找,无必要时不推荐
注意键类型和可变性 —— 字典添加失败往往卡在这儿
字典的 key 必须是不可变类型。你试图用列表、集合或自定义类实例当 key,哪怕只是想“添加”,Python 都会在赋值那步直接报 TypeError: unhashable type。
常见错误现象:d[[1, 2]] = "bad"、d[{"a": 1}] = "nope"、甚至 d[my_obj] = "oops"(而 my_obj 没实现 __hash__)。
使用场景:几乎全是字符串、数字、元组(且元组里不能含可变对象)。
- 元组作 key 没问题:
d[(1, "a")] = "ok"✅;但d[(1, [2])] = "fail"❌,因为列表不可哈希 - 自定义类想当 key,必须定义
__hash__和__eq__,且实例状态不能变(否则哈希值变化会导致查不到) - 字符串 key 最安全,但注意前后空格、大小写、编码隐式转换(比如从 JSON 解析来的 key 可能带不可见字符)
update() 当深拷贝用。










