我经常需要创建一个或两个项目彼此不同的词汇。这是我通常做的事情:
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})
当然,我可以使用分号将两个命令压缩到一个物理行中,但这对我来说非常难看。还有其他选择吗?
答案 0 :(得分:38)
我认为最简单的方法是:
new_dict = {**old_dict, 'changed_val': value, **other_new_vals_as_dict}
答案 1 :(得分:21)
setup2 = dict(setup1.items() + {'param1': val10, 'param2': val20}.items())
这样,如果setup1
中不存在新密钥,则会添加新密钥,否则会替换旧密钥/值对。
答案 2 :(得分:18)
您可以在字典构造函数中使用关键字参数进行更新
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()
会创建浅副本。
答案 3 :(得分:15)
为此构建一个函数。
当您在代码中使用它时,您的意图会更清晰,并且您可以在一个地方处理复杂的决策(例如,深拷贝和浅拷贝)。
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
可以做的对象)。
答案 4 :(得分:13)
setup2 = dict((k, {'param1': val10, 'param2': val20}.get(k, v))
for k, v in setup1.iteritems())
仅当更新词典的所有键都已包含在setup1
中时才有效。
如果您的所有键都是字符串,您也可以
setup2 = dict(setup1, param1=val10, param2=val20)
答案 5 :(得分:2)
如果您只需要使用多个词典中的项目创建新词典,则可以使用:
dict(a.items() + b.items())
如果“a”和“b”都有一些相同的键,则结果将具有b的值。 如果您使用的是Python 3,则连接将不起作用,但您可以通过将生成器冻结到列表或使用itertools.chain函数来执行相同的操作。
答案 6 :(得分:0)
您可以使用UserDict
包装器编写自己的类,只需添加dict
类似
# setup1 is of Dict type (see below)
setup2 = setup1 + {'param1': val10}
你所要做的就是
UserDict
作为基类__add__
方法。类似于:
class Dict(dict):
def __add__(self, _dict):
if isinstance(_dict, dict):
tmpdict = Dict(self)
tmpdict.update(_dict)
return tmpdict
else:
raise TypeError
def __radd__(self, _dict):
return Dict.__add__(self, _dict)
答案 7 :(得分:0)
这是Adam Matan发布的好答案的扩展:
def copy_dict(d, diffs={}, **kwargs):
res = dict(d)
res.update(diffs)
res.update(kwargs)
return res
唯一的区别是增加了kwargs。 现在可以写
setup2 = copy_dict(setup1, {'param1': val10, 'param2': val20})
或
setup2 = copy_dict(setup1, param1=val10, param2=val20)
答案 8 :(得分:0)
我喜欢这一行(在from itertools import chain
之后):
d3 = dict(chain(d1.items(), d2.items()))
(感谢juanpa.arrivillaga的改进!)