a= {u'1009': {u'Avg': 188,
u'amount_spent': 2820,
u'size': 15,
u'users': {u'0': 346041,
u'1': 658546,
u'2': 658194,
u'3': 658316
}},
u'1056': {u'Avg': 140,
u'amount_spent': 140,
u'size': 1,
u'users': {u'0': 645767}},
u'1103': {u'Avg': 95,
u'amount_spent': 285,
u'size': 3,
u'users': {u'0': 339285, u'1': 658440}}
b = {u'1009': {u'Avg': 246.25,
u'amount_spent': 1970,
u'size': 8,
u'users': {u'0': 61496,
u'1': 1350,
u'2': 164852,
u'3': 517760,
u'4': 576458,
u'5': 203840,
u'6': 52239,
u'7': 516672}},
u'1056': {u'Avg': 170,
u'amount_spent': 680,
u'size': 4,
u'users': {u'0': 503737, u'1': 624418, u'2': 642471}}}
我有多个嵌套字典,我想通过它们的内部键合并添加,所以我的输出看起来像这样。
c = {u'1009': {u'Avg': 434.25,
u'amount_spent': 4790,
u'size': 23,
u'users': {u'0': 61496,
u'1': 1350,
u'2': 164852,
u'3': 517760,
u'4': 576458,
u'5': 203840,
u'6': 52239,
u'7': 516672,
u'8': 346041,
u'9': 658546,
u'10': 658194,
u'11': 658316
}},,,,,
我们的想法是只添加已存在的键的值。如果他们不只是添加新密钥。使用+
opperand添加它们不起作用。我怎么能这样做?
EDIT1: 合并用户密钥的许多问题是由于值本身就是user_id。因此,它们无法添加,而只是附加在用户密钥中。解决此问题的一种方法是将用户键值作为数组:
{u'1009': {u'Avg': 188,
u'amount_spent': 2820,
u'size': 15,
u'users': [346041,
658546,
658194,
658316]},
u'1056': {u'Avg': 140, u'amount_spent': 140, u'size': 1, u'users': [645767]}
希望这有帮助!
答案 0 :(得分:1)
这是一个修补的想法,这个递归函数将字典的内容添加到一起。
def add_dict(x, y):
n = {}
inter = x.keys() & y.keys()
outer = (x.keys() | y.keys()) - inter
for k in x.keys() & y.keys():
l, r = x[k], y[k]
if isinstance(l, dict):
n[k] = add_dict(l, r)
continue
n[k] = l + r
for k in outer:
l, r = x.get(k), y.get(k)
if l: n[k] = l
if r: n[k] = r
return n
c = add_dict(a, b)
答案 1 :(得分:1)
这是一个递归迭代两个字典的k,v的函数,并对公共密钥的值求和(在字符串总和的情况下要注意结果)。不常见的键也包含在最终字典中,然后返回。
我不确定这是你在寻找什么,因为在你的例子中,一些公共密钥的值被加在一起,而其他公用键则没有。
我希望这对你来说是一个很好的起点。
def merge_dict(dictA, dictB):
r = {}
common_k = [k for k in dictA if k in dictB]
common_k += [k for k in dictB if k in dictA]
common_k = set(common_k)
for k, v in dictA.items():
#add unique k of dictA
if k not in common_k:
r[k] = v
else:
#add inner keys if they are not containing other dicts
if type(v) is not dict:
if k in dictB:
r[k] = v + dictB[k]
else:
#recursively merge the inner dicts
r[k] = merge_dict(dictA[k], dictB[k])
#add unique k of dictB
for k, v in dictB.items():
if k not in common_k:
r[k] = v
return r
#test
dictA = {'any key':1, 'point':{'x':2, 'y':3}}
dictB = {'any key':1, 'point':{'x':2, 'y':3, 'z':0, 'even more nested':{'w':99}}, 'extra':8}
merge_dict(dictA, dictB)
{'any key': 2,
'point': {'x': 4, 'y': 6, 'z': 0, 'even more nested': {'w': 99}},
'extra': 8}
答案 2 :(得分:-1)
您可以使用字典理解递归:
import itertools
a = {'1009': {'Avg': 188, 'amount_spent': 2820, 'size': 15, 'users': {'0': 346041, '1': 658546, '2': 658194, '3': 658316}}, '1056': {'Avg': 140, 'amount_spent': 140, 'size': 1, 'users': {'0': 645767}}, '1103': {'Avg': 95, 'amount_spent': 285, 'size': 3, 'users': {'0': 339285, '1': 658440}}}
b = {'1009': {'Avg': 246.25, 'amount_spent': 1970, 'size': 8, 'users': {'0': 61496, '1': 1350, '2': 164852, '3': 517760, '4': 576458, '5': 203840, '6': 52239, '7': 516672}}, '1056': {'Avg': 170, 'amount_spent': 680, 'size': 4, 'users': {'0': 503737, '1': 624418, '2': 642471}}}
def full_sum(d1, d2):
v1 = {a:list(b) for a, b in itertools.groupby(sorted(list(d1.items())+list(d2.items()), key=lambda x:x[0]), key=lambda x:x[0])}
return {a:sum(_i for h, _i in b) if all(not isinstance(i, dict) for d, i in b) else full_sum(*[i for _, i in b]) for a, b in v1.items()}
def add_dicts(_a, _b):
return {c:full_sum(d, f) for [c, d], [e, f] in zip(_a.items(), _b.items())}
print(add_dicts(a, b))
输出:
{'1009': {'Avg': 434.25, 'amount_spent': 4790, 'size': 23, 'users': {'0': 407537, '1': 659896, '2': 823046, '3': 1176076, '4': 576458, '5': 203840, '6': 52239, '7': 516672}}, '1056': {'Avg': 310, 'amount_spent': 820, 'size': 5, 'users': {'0': 1149504, '1': 624418, '2': 642471}}}