如何在一行代码中复制并修改字典
我经常需要创建一些字典,它们之间只差一两个项目。以下是我通常的做法:
setup1 = {'param1': val1,
'param2': val2,
'param3': val3,
'param4': val4,
'paramN': valN}
setup2 = copy.deepcopy(dict(setup1))
setup2.update({'param1': val10,
'param2': val20})
程序中有一个时刻,setup2
是 setup1
的完全复制,这让我有点紧张,因为我担心在程序运行的某个阶段,这两行代码可能会分开,这样就容易出现很多错误。
理想情况下,我希望能用一行代码完成这个操作(类似这样):
setup2 = dict(setup1).merge({'param1': val10,
'param2': val20})
当然,我可以用分号把两个命令挤在一行里,但我觉得这样看起来很难看。还有其他选择吗?
11 个回答
20
解决方案
为此创建一个函数。
这样在代码中使用时,意图会更清晰,而且你可以在一个地方处理复杂的决策(比如深拷贝和浅拷贝的选择)。
def copy_dict(source_dict, diffs):
"""Returns a copy of source_dict, updated with the new key-value
pairs in diffs."""
result=dict(source_dict) # Shallow copy, see addendum below
result.update(diffs)
return result
现在这个拷贝是原子的,假设没有线程参与:
setup2=copy_dict(setup1, {'param1': val10, 'param2': val20})
补充 - 深拷贝
对于基本数据类型(比如整数和字符串),其实不需要做深拷贝:
>>> d1={1:'s', 2:'g', 3:'c'}
>>> d2=dict(d1)
>>> d1[1]='a'
>>> d1
{1: 'a', 2: 'g', 3: 'c'}
>>> d2
{1: 's', 2: 'g', 3: 'c'}
如果你确实需要深拷贝,可以使用 copy
模块:
result=copy.deepcopy(source_dict) # Deep copy
而不是:
result=dict(setup1) # Shallow copy
确保你字典里的所有对象都支持深拷贝(任何可以被 pickled
的对象都可以)。
55
你可以在字典构造函数中使用关键字参数来进行更新。
new = dict(old, a=1, b=2, c=3)
# You can also unpack your modifications
new = dict(old, **mods)
这和下面的写法是一样的:
new = old.copy()
new.update({"a": 1, "b": 2, "c": 3})
注意事项
dict.copy()
创建的是一个浅拷贝。- 所有的键必须是字符串,因为它们是作为关键字参数传递的。
134
在我看来,最简单的方法就是这样:
new_dict = {**old_dict, 'changed_val': value, **other_new_vals_as_dict}