结合词典的两个词典(Python)
有没有简单的方法来结合Python中的字典的两个字典?这是我需要:结合词典的两个词典(Python)
dict1 = {'A' : {'B' : 'C'}}
dict2 = {'A' : {'D' : 'E'}}
result = dict_union(dict1, dict2)
# => result = {'A' : {'B' : 'C', 'D' : 'E'}}
我创建了一个强力功能做的,但我一直在寻找一个更紧凑的解决方案:
def dict_union(train, wagon):
for key, val in wagon.iteritems():
if not isinstance(val, dict):
train[key] = val
else:
subdict = train.setdefault(key, {})
dict_union(subdict, val)
你可以继承dict
,敷原dict.update()
方法与一个版本,这将调用update()
在subdicts而不是直接覆盖subdicts。尽管如此,这最终可能会比现有的解决方案花费更多的精力。
是的,但你需要确保正在更新的字典中的任何字典也是你的子类。 – Cosmologicon 2011-06-06 18:14:42
必须是递归的,因为字典可以嵌套。这是我第一次接触它,你可能想要定义你的行为,当字典嵌套在不同的深度。
def join(A, B):
if not isinstance(A, dict) or not isinstance(B, dict):
return A or B
return dict([(a, join(A.get(a), B.get(a))) for a in set(A.keys()) | set(B.keys())])
def main():
A = {'A': {'B': 'C'}, 'D': {'X': 'Y'}}
B = {'A': {'D': 'E'}}
print join(A, B)
从参数{'A':{'B':'C'}}和{'A':'F'}的OP函数返回不同的结果。不过,我不确定OP是否已经考虑过这个例子。 – Cosmologicon 2011-06-06 18:43:44
是啊,你说得对,这就是我说的关于当字迹深度不同时的行为。你必须定义你自己的。我只是返回第一个非None或A或B的。你可以做'B或A',这是他的代码所做的,或者其他任何冲突解决方案。 – 2011-06-06 18:53:50
该解决方案非常紧凑。它的丑陋,但你问一些相当复杂的行为:
dict_union = lambda d1,d2: dict((x,(dict_union(d1.get(x,{}),d2[x]) if
isinstance(d2.get(x),dict) else d2.get(x,d1.get(x)))) for x in
set(d1.keys()+d2.keys()))
至于我没有enaugh信息,但无论如何请在下面找到我的示例代码:
dict1 = {'A' : {'B' : 'C'}}
dict2 = {'A' : {'D' : 'E'}, 'B':{'C':'D'}}
output = {}
for key in (set(dict1) | set(dict2):
output[key] = {}
(key in dict1 and output[key].update(dict1.get(key)))
(key in dict2 and output[key].update(dict2.get(key)))
这里是一个类, RUDict(用于递归更新字典),实现您正在寻找的行为:
class RUDict(dict):
def __init__(self, *args, **kw):
super(RUDict,self).__init__(*args, **kw)
def update(self, E=None, **F):
if E is not None:
if 'keys' in dir(E) and callable(getattr(E, 'keys')):
for k in E:
if k in self: # existing ...must recurse into both sides
self.r_update(k, E)
else: # doesn't currently exist, just update
self[k] = E[k]
else:
for (k, v) in E:
self.r_update(k, {k:v})
for k in F:
self.r_update(k, {k:F[k]})
def r_update(self, key, other_dict):
if isinstance(self[key], dict) and isinstance(other_dict[key], dict):
od = RUDict(self[key])
nd = other_dict[key]
od.update(nd)
self[key] = od
else:
self[key] = other_dict[key]
def test():
dict1 = {'A' : {'B' : 'C'}}
dict2 = {'A' : {'D' : 'E'}}
dx = RUDict(dict1)
dx.update(dict2)
print(dx)
if __name__ == '__main__':
test()
>>> import RUDict
>>> RUDict.test()
{'A': {'B': 'C', 'D': 'E'}}
>>>
这不是一个'dict'结合。 – 2011-06-06 18:12:59
我不清楚你在结构不匹配时想要发生什么。例如,如果dict3 = {'A':'F'},那么在这里使用你的版本,dict_union(dict3,dict2)会抛出一个TypeError。这是期望的行为? – Cosmologicon 2011-06-06 18:25:21
相关(但更简单):http://*.com/questions/1031199/adding-dictionaries-in-python – Gilles 2012-01-17 13:29:05