减去两个嵌套字典python的值

时间:2016-08-05 10:59:39

标签: python dictionary nested

我需要获得两个嵌套字典的delta:

我正在使用这样的函数来获取嵌套字典

def _get_data(self):
    duplicates = defaultdict(list) # to append tuples into a dictionary
    counter_dict = AutoVivification()
    vpls_dict = AutoVivification()

    fpcs = self._get_slot_fpcs_online()
    pattern = "GOT:\s+(\d+).*([0-9A-F]{2,2}\:[0-9A-F]{1,2}\:[0-9A-F]{1,2}\:[0-9A-F]{1,2}\:[0-9A-F]{1,2}\:[0-9A-F]{1,2})\s+\d{4}\s+(\d\s+\d).*(\d\s+\d+/\d+)"
    regex = re.compile(pattern,re.IGNORECASE)

    for i in fpcs:
        if i == '11':
            for pfe in range(2):
                cmd = self._conn.rpc.request_pfe_execute(target='fpc' + str(i),command='show l2metro '+str(pfe)+' mac hw')                  
                cmd_str = etree.tostring(cmd)
                for x in regex.findall(cmd_str):
                    if x[2] =='0   0' and x[3] != '7 255/255':  
                        duplicates[i].append(x)
        else:
            cmd = self._conn.rpc.request_pfe_execute(target='fpc' + str(i),command='show l2metro 0 mac hw') 
            cmd_str = etree.tostring(cmd)
            for x in regex.findall(cmd_str):
                if x[2] =='0   0' and x[3] != '7 255/255':  
                    duplicates[i].append(x)

    for k,v in duplicates.iteritems():
        for j in v:
            cmd_vpls = self._conn.rpc.get_l2_learning_routing_instances()
            vpls_instance = ''.join(cmd_vpls.xpath("//l2ald-rtb-entry[l2rtb-id=" + '"' + str(j[0]) + '"'"]/l2rtb-name//text()")[0])
            vpls_dict[k][j[1]][j[3]][j[0]][vpls_instance] = self._conn.cli('show configuration routing-instances '+ vpls_instance + ' forwarding-options family vpls filter',warning=False).split('\n')[1].replace('input','').replace(';','')
            counter_cmd = self._conn.rpc.get_firewall_filter_information(filtername=str(vpls_dict[k][j[1]][j[3]][j[0]][vpls_instance]).strip())
            counter_dict[k][j[1]][j[3]][vpls_instance][vpls_dict[k][j[1]][j[3]][j[0]][vpls_instance].strip()] = ''.join(counter_cmd.xpath('./filter-information/policer/packet-count//text()')).replace('\n','')
    return counter_dict

counter_dict结果看起来像:

{' 10':{' 07:72:9d:dc:4c':{' 0 255/255':{&#39 ; 128379':{' CDALJ1 / 17223002010':' 91304'}}},         ' 00:0f:bb:fa:25:fd':{' 0 255/255':{' 232367':{' CDALJ1 / 14100001093228& #39;:' 1585097'}}},         ' 00:1b:c0:f2:f4:fa':{' 0 255/255':{' 156420':{' CDALJ1 / 08903762011& #39;:' 0'},                                             ' 166980':{' CDALJ1 / 19369922011':' 0'}}},         ' 88:e0:f3:61:d8:01':{' 0 255/255':{' 182099':{' CDALJ1 / 11274452012& #39;:' 0'}}},         ' ec:13:db:0a:95:01':{' 0 255/255':{' 182099':{' CDALJ1 / 11274452012& #39;:' 0'}}}},

' 11':{' 00:0c:07:ac:75':{' 0 255/255':{' 232173':{' CDALJ1 / 14100001093242':' 0'}}},         ' 00:00:0c:07:ac:f5':{' 0 255/255':{' 293667':{' CDALJ1 / 14100001095054& #39;:' 2723092'}}},         ' 00:00:0c:07:ac:f6':{' 0 255/255':{' 298967':{' CDALJ1 / 14100001095106& #39;:' 0'}}},         ' 00:00:0c:07:ac:f7':{' 0 255/255':{' 298969':{' CDALJ1 / 14100001095107& #39;:' 0'}}},         ' 07:72:9d:dc:4c':{' 0 255/255':{' 128379':{' CDALJ1 / 17223002010& #39;:' 91304'}}}

[......]

我试图获得内部价值保持字典结构的增量:

mac_dict1 = _get_data()

{' 10':{' 07:72:9d:dc:4c':{' 0 255/255':{&#39 ; 128379':{' CDALJ1 / 17223002010':' 91304'}}},         ' 00:0f:bb:fa:25:fd':{' 0 255/255':{' 232367':{' CDALJ1 / 14100001093228& #39;:' 1585097'}}}

sleep5

mac_dict2 = _get_data()

{' 10':{' 07:72:9d:dc:4c':{' 0 255/255':{&#39 ; 128379':{' CDALJ1 / 17223002010':' 91310'}}},         ' 00:0f:bb:fa:25:fd':{' 0 255/255':{' 232367':{' CDALJ1 / 14100001093228& #39;:' 1585100'}}}

result = get_diff(mac_dict1,mac_dict2)

结果应该提供如下结果:

{' 10':{' 07:72:9d:dc:4c':{' 0 255/255':{&#39 ; 128379':{' CDALJ1 / 17223002010':' 6'}}},         ' 00:0f:bb:fa:25:fd':{' 0 255/255':{' 232367':{' CDALJ1 / 14100001093228& #39;:' 3'}}}

你能否提供关于如何做到这一点(不是代码)的任何提示或提示?

由于

1 个答案:

答案 0 :(得分:1)

您可以使用简单的递归函数执行此操作,将str值转换为int,并在dict的情况下减去或递归:

def subtract(x, y):
    if isinstance(x, dict) and isinstance(y, dict):
        return {key: subtract(x[key], y[key]) for key in x if key in y}
    else:
        return str(int(x) - int(y))

使用给定输入运行它:

d1 = {
    '10': {
        '00:07:72:9d:dc:4c': {'0 255/255': {'128379': {'CDALJ1/17223002010': '91304'}}},
        '00:0f:bb:fa:25:fd': {'0 255/255': {'232367': {'CDALJ1/14100001093228': '1585097'}}}
    }
}
d2 = {
    '10': {
        '00:07:72:9d:dc:4c': {'0 255/255': {'128379': {'CDALJ1/17223002010': '91310'}}},
        '00:0f:bb:fa:25:fd': {'0 255/255': {'232367': {'CDALJ1/14100001093228': '1585100'}}}
    }
}

print subtract(d2, d1)

格式化输出:

{
    '10': {
        '00:07:72:9d:dc:4c': {'0 255/255': {'128379': {'CDALJ1/17223002010': '6'}}}, 
        '00:0f:bb:fa:25:fd': {'0 255/255': {'232367': {'CDALJ1/14100001093228': '3'}}}
    }
}

请注意,如果您的输入包含应该被解释为dict的{​​{1}}和str之外的任何其他类型的值,示例代码将失败。