我需要获得两个嵌套字典的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'}}}
你能否提供关于如何做到这一点(不是代码)的任何提示或提示?
由于
答案 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
之外的任何其他类型的值,示例代码将失败。