python 3.5+ 用 {**d} 可浅拷贝字典并动态注入键值,外层独立但嵌套对象仍引用;不支持深拷贝,需用 copy.deepcopy()。

Python 本身没有“展开运算符”(如 JavaScript 中的 ...)用于字典浅拷贝,但自 Python 3.5 起,字典解包语法({**d})提供了类似功能,它是最常用、最直观的浅拷贝加动态键值注入方式。
用 {**d} 一次性完成浅拷贝 + 新键值注入
该语法会创建一个新字典,把原字典所有键值对“展开”进去,再允许你直接添加或覆盖键值:
- 原字典不会被修改
- 外层键值是独立副本(id 不同),但嵌套的可变对象(如 list、dict)仍是引用
- 若新键与原字典重复,新值会覆盖原值
示例:
original = {'name': 'Alice', 'scores': [85, 92]}
new = {**original, 'age': 28, 'updated': True}
print(new) # {'name': 'Alice', 'scores': [85, 92], 'age': 28, 'updated': True}
print(original['scores'] is new['scores']) # True → 嵌套列表未复制
结合变量动态插入键名和值
键名和值都可以来自变量,只需确保键名为字符串(或使用 str(key) 转换):
key_name = 'status'
key_value = 'active'
extra = {key_name: key_value}
<p>new_dict = {<strong>original, </strong>extra}</p><h1>或一步写成:{<strong>original, </strong>{key_name: key_value}}</h1>注意:不能直接写 {**original, key_name: key_value}(语法错误),必须保证右侧是完整字典表达式。
对比其他浅拷贝方式的适用场景
-
dict.copy():适合只拷贝不加字段,语义清晰 -
dict(d):兼容旧版本,但不可读性略低 -
{**d}:唯一支持“拷贝+扩展”原子操作的语法,推荐用于构造配置、API 参数、日志上下文等场景
例如构建 HTTP 请求参数:
base_params = {'format': 'json', 'timeout': 30}
user_params = {'user_id': 123, 'include_profile': True}
final_params = {**base_params, **user_params, 'timestamp': int(time.time())}
重要提醒:这不是深拷贝
如果你的字典含有嵌套字典或列表,并希望修改副本不影响原数据,{**d} 无法满足。此时必须用 copy.deepcopy(),或手动处理嵌套结构:
import copy
original = {'a': 1, 'meta': {'x': 100}}
deep_new = copy.deepcopy(original)
deep_new['meta']['x'] = 999 # 不影响 original










