2016-08-05 105 views
-3

我需要得到兩個嵌套字典的三角洲:值。減去

我用這樣的一個函數來獲取一個嵌套的字典

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':{'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'}}}, '00:1b: c0:f2:f4:fa':{' 0 255/255':{'156420':{'CDALJ1/08903762011':'0'}, '166980':{'CDALJ1/19369922011':'0'}}}, '88:e0:f3: 61:d8:01':{'0 255/255':{'182099':{'CDALJ1/11274452012':'0'}}}, 'ec:13:db:0a:95:01':{ '0 255/255':{'182099':{'CDALJ1/11274452012':'0'}}}},

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

[......]

我試圖獲得內值的增量保持字典結構:

mac_dict1 = _get_data( )

{'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'}}}

sleep5

= mac_dict2 _get_data()

{ '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'}}}

結果= get_diff(mac_dict1,mac_dict2)

結果應該是提供這樣的結果:

{ '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'}}}

您能否提供我提示或提示如何做到這一點(而不是代碼)?

感謝

+0

確實有可能。 – msvalkon

+0

我正在投票結束這個問題作爲題外話,因爲這不是一個代碼寫作服務。 – Kasramvd

+0

如果你想得到一個正確的答案,你最好用你到目前爲止已經嘗試過的代碼來更新你的問題,並告訴我們你的代碼存在的問題。 – Kasramvd

回答

1

你可以做到這一點與簡單的遞歸函數,它會變成strint覈減或遞歸的情況下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'}}} 
    } 
} 

請注意,如果您的輸入包含dictstr之間的任何其他類型的值,則應將其解釋爲int,但示例代碼會失敗。

+0

謝謝你,驚人的答案。 – psagrera