首页 > 解决方案 > 比较两个嵌套字典并将它们的值的差异存储到一个新字典中

问题描述

我有一本字典(long_dict),里面有 3 类不同人的数据。我正在尝试比较特定类别(category_2)的值并将它们的差异分别存储到新字典中。

long_dict = {

'PERSON1':{
'category_1' :{
},
'category_2': {
'a': 20,
'b': 40,
'c': 60,
'd': 45
},
'category_3': {
}
},

'PERSON2': {
'category_1' :{
},
'category_2': {
'a': 30,
'b': 10,
'c': 40,
'd': 55
},
'category_3': {
}
},

'PERSON3': {
'category_1' :{
},
'category_2': {
'a': 60,
'b': 10,
'c': 35,
'd': 25
},
'category_3: {
}
},
'PERSON4': {
'category_1' :{
},
'category_2': {
'a': 30,
'b': 15,
'c': 65,
'd': 55
},
'category_3': {
}
}
}

我正在寻找一个存储值差异的字典;像这样的东西。

result = {

'PERSON1':{
'PERSON2' :{
'diff_a': ...,
'diff_b': ...,
'diff_c': ...,
'diff_d': ...
},
'PERSON3': {
'diff_a': ...,
'diff_b': ...,
'diff_c': ...,
'diff_d': ...
},
'PERSON4': {
'diff_a': ...,
'diff_b': ...,
'diff_c': ...,
'diff_d': ...
}
},
'PERSON2':{
'PERSON1' :{
'diff_a': ...,
'diff_b': ...,
'diff_c': ...,
'diff_d': ...
},
'PERSON3': {
'diff_a': ...,
'diff_b': ...,
'diff_c': ...,
'diff_d': ...
},
'PERSON4': {
'diff_a': ...,
'diff_b': ...,
'diff_c': ...,
'diff_d': ...
 }
 },
'PERSON3':{
'PERSON1' :{
'diff_a': ...,
'diff_b': ...,
'diff_c': ...,
'diff_d': ...
},
'PERSON2': {
'diff_a': ...,
'diff_b': ...,
'diff_c': ...,
'diff_d': ...
},
'PERSON4': {
'diff_a': ...,
'diff_b': ...,
'diff_c': ...,
'diff_d': ...
}
},

'PERSON4':{
'PERSON1' :{
'diff_a': ...,
'diff_b': ...,
'diff_c': ...,
'diff_d': ...
},
'PERSON2': {
'diff_a': ...,
'diff_b': ...,
'diff_c': ...,
'diff_d': ...
},
'PERSON3': {
'diff_a': ...,
'diff_b': ...,
'diff_c': ...,
'diff_d': ...
}
}
}

到目前为止,我已经尝试过:

abc = dict()
xyz = dict()
fin = dict()
i = 0
for k, v in long_dict.items():
for a, b in long_dict.items():
    if k != a:
        for k2, v2 in v.items():
            for a2, b2 in b.items():
                if k2 == a2 == "category_2":
                    for k3, v3 in v2.items():
                        for a3, b3 in b2.items():
                            if k3 == a3:
                                abc[k3] = abs(v3-b3)
        xyz[a] = abc
        i+=1                        
        if i > 3:
            fin[k] = xyz
            i=0

而且,这就是我在 print(fin) 上得到的:

{'PERSON2': {'PERSON2': {'a': 30, 'b': 5, 'c': 30, 'd': 30}, 'PERSON3': {'a': 30, 'b': 5, 'c': 30, 'd': 30}, 'PERSON4': {'a': 30, 'b': 5, 'c': 30, 'd': 30}, 'PERSON1': {'a': 30, 'b': 5, 'c': 30, 'd': 30}}, 'PERSON3': {'PERSON2': {'a': 30, 'b': 5, 'c': 30, 'd': 30}, 'PERSON3': {'a': 30, 'b': 5, 'c': 30, 'd': 30}, 'PERSON4': {'a': 30, 'b': 5, 'c': 30, 'd': 30}, 'PERSON1': {'a': 30, 'b': 5, 'c': 30, 'd': 30}}, 'PERSON4': {'PERSON2': {'a': 30, 'b': 5, 'c': 30, 'd': 30}, 'PERSON3': {'a': 30, 'b': 5, 'c': 30, 'd': 30}, 'PERSON4': {'a': 30, 'b': 5, 'c': 30, 'd': 30}, 'PERSON1': {'a': 30, 'b': 5, 'c': 30, 'd': 30}}}

标签: jsonpython-3.xdictionary

解决方案


比较和存储值的更有效方法是只比较和存储每个唯一比较一次(而不是为比较中涉及的每个 dict 键比较和存储相同的比较)。您可以使用itertools.combinations它来保持相当简单并通过元组键访问每个比较(下面的方法假设每个比较的类别字典都包含相同的键 - 如果不是,那么您将不得不添加一些额外的检查)。

from itertools import combinations

d = {'PERSON1':{'category_1' :{}, 'category_2': {'a': 20, 'b': 40, 'c': 60, 'd': 45}, 'category_3': {}}, 'PERSON2': {'category_1' :{}, 'category_2': {'a': 30, 'b': 10, 'c': 40, 'd': 55}, 'category_3': {}}, 'PERSON3': {'category_1' :{}, 'category_2': {'a': 60, 'b': 10, 'c': 35, 'd': 25}, 'category_3': {}}, 'PERSON4': {'category_1' :{}, 'category_2': {'a': 30, 'b': 15, 'c': 65, 'd': 55}, 'category_3': {}}}

compare = {}
for a, b in combinations(sorted(d.keys()), 2):
    acat = d[a]['category_2']
    bcat = d[b]['category_2']
    compare[(a, b)] = {k: abs(acat[k] - bcat[k]) for k in acat}

print(compare)
# {('PERSON1', 'PERSON2'): {'a': 10, 'b': 30, 'c': 20, 'd': 10}, ('PERSON1', 'PERSON3'): {'a': 40, 'b': 30, 'c': 25, 'd': 20}, ('PERSON1', 'PERSON4'): {'a': 10, 'b': 25, 'c': 5, 'd': 10}, ('PERSON2', 'PERSON3'): {'a': 30, 'b': 0, 'c': 5, 'd': 30}, ('PERSON2', 'PERSON4'): {'a': 0, 'b': 5, 'c': 25, 'd': 0}, ('PERSON3', 'PERSON4'): {'a': 30, 'b': 5, 'c': 30, 'd': 30}}

推荐阅读