2016-05-02 13 views
0

2つのjson辞書を比較し、どのアイテムが失われ、変更され、追加されたかを調べるためのスクリプトをスタックオーバーフローの助けを借りて書いています。ネストされた辞書のキーの追加と管理

私は現在、次のを持っている -

import json 
from pprint import pprint 

def new_keys(d1, d2, result={}): 
    for key, d1_val in d1.iteritems(): 
     if key not in d2: 
       result[key] = d1_val 
     else: 
      if isinstance(d1_val, dict) and isinstance(d2[key], dict): 
       # Don't pass result. 
       new_result = {} 
       new_keys(d1[key], d2[key], new_result) 
       # If new_result is not empty 
       if new_result: 
        result[key] = new_result 
      else: 
       if d1_val != d2[key]: 
        result[key] = d2[key] 
    for key, d2_val in d2.iteritems(): 
     if key not in d1: 
      result[key] = d2_val 
    return result 

with open("before.json") as data_file: 
    before = json.loads(data_file.read()) 

with open("after.json") as data_file: 
    after = json.loads(data_file.read()) 

pprint(new_keys(before,after)) 

私は流行語を追加することができています「失われたが、変更、および追加」キーに、しかし、入れ子になっていません。

たとえば、私は次のような出力が発生し得ることができますが:

{u'vrfs': {u'default': {u'routes': {('added', u'3.3.3.3/32'): {u'directlyConnected': True, 
                   u'hardwareProgrammed': True, 
                   u'kernelProgrammed': True, 
                   u'routeAction': u'drop', 
                   u'routeType': u'static', 
                   u'vias': []}, 
            ('lost', u'1.1.1.1/32'): {u'directlyConnected': True, 
                   u'hardwareProgrammed': True, 
                   u'kernelProgrammed': True, 
                   u'routeAction': u'drop', 
                   u'routeType': u'static', 
                   u'vias': []}, 
            ('lost', u'5.5.5.0/24'): {u'directlyConnected': False, 
                   u'hardwareProgrammed': True, 
                   u'kernelProgrammed': True, 
                   u'metric': 0, 
                   u'preference': 200, 
                   u'routeAction': u'forward', 
                   u'routeType': u'eBGP', 
                   u'vias': [{u'interface': u'Ethernet3', 
                      u'nexthopAddr': u'192.168.1.10'}]}, 
            u'2.2.2.2/32': {('changed', u'routeAction'): u'forward', 
                ('changed', u'vias'): [{u'interface': u'Ethernet4'}]}}}}} 

私が見たいもの:

{u'vrfs': {u'default': {u'routes': {'added': { 
             u'3.3.3.3/32'): {u'directlyConnected': True, 
                   u'hardwareProgrammed': True, 
                   u'kernelProgrammed': True, 
                   u'routeAction': u'drop', 
                   u'routeType': u'static', 
                   u'vias': []}, 
            'lost': { 
             u'1.1.1.1/32'): {u'directlyConnected': True, 
                   u'hardwareProgrammed': True, 
                   u'kernelProgrammed': True, 
                   u'routeAction': u'drop', 
                   u'routeType': u'static', 
                   u'vias': []}, 
             u'5.5.5.0/24'): {u'directlyConnected': False, 
                   u'hardwareProgrammed': True, 
                   u'kernelProgrammed': True, 
                   u'metric': 0, 
                   u'preference': 200, 
                   u'routeAction': u'forward', 
                   u'routeType': u'eBGP', 
                   u'vias': [{u'interface': u'Ethernet3', 
                   u'nexthopAddr': u'192.168.1.10'}]}, 
            'changed': { 
             u'2.2.2.2/32': {u'routeAction': u'forward', 
                u'vias': [{u'interface': u'Ethernet4'}]}}}}} 

私は(静的辞書のキーを管理する方法に困惑しています変更、失われた、追加された、変更された)私の元のjsonの内部の可変キーで働いている間。

ご協力いただきましてありがとうございます。

編集:近づいた!しかし、私のコードはすべての発生を考慮していません。

新コード -

import json 
from pprint import pprint 

def new_keys(d1, d2, result={}): 
    for key, d1_val in d1.iteritems(): 
     if key not in d2: 
      result['Lost'] = {} 
      result['Lost'][key] = d1_val 
     else: 
      if isinstance(d1_val, dict) and isinstance(d2[key], dict): 
       # Don't pass result. 
       new_result = {} 
       new_keys(d1[key], d2[key],new_result) 
       # If new_result is not empty 
       if new_result: 
        result[key] = new_result 
      else: 
       if d1_val != d2[key]: 
        result['Changed'] = {} 
        result['Changed'][key] = d2[key] 
    for key, d2_val in d2.iteritems(): 
     if key not in d1: 
      result['New'] = {} 
      result['New'][key] = d2_val 
    return result 

with open("before.json") as data_file: 
    before = json.loads(data_file.read()) 

with open("after.json") as data_file: 
    after = json.loads(data_file.read()) 

pprint(new_keys(before,after)) 

新しい出力 - それが唯一の最初の変更を見て注意してください...私は空のDICに辞書をオーバーライドするからだと信じている...しかし、どのように私はそれを初期化しますか?

{u'vrfs': {u'default': {u'routes': {u'2.2.2.2/32': {'Changed': {u'vias': [{u'interface': u'Ethernet4'}]}}, 
            'Lost': {u'1.1.1.1/32': {u'directlyConnected': True, 
                  u'hardwareProgrammed': True, 
                  u'kernelProgrammed': True, 
                  u'routeAction': u'drop', 
                  u'routeType': u'static', 
                  u'vias': []}}, 
            'New': {u'3.3.3.3/32': {u'directlyConnected': True, 
                  u'hardwareProgrammed': True, 
                  u'kernelProgrammed': True, 
                  u'routeAction': u'drop', 
                  u'routeType': u'static', 
                  u'vias': []}}}}}} 
+0

をあなたが掲示秒ファイルが有効なJSON/pythonのではありません、あなたはいくつかの余分を持っている ")" – luke14free

+0

luke14free @それはファイルではありません。私の目標を視覚的に表現するために手動で入力した例です。 – exilent

答えて

0

はそれを考え出した -

import json 
from pprint import pprint 

def new_keys(d1, d2, result={}): 
    for key, d1_val in d1.iteritems(): 
     if key not in d2: 
      if not result.has_key('lost'): 
       result['lost'] = {} 
       result['lost'][key] = d1_val 
      else: 
       result['lost'][key] = d1_val 
     else: 
      if isinstance(d1_val, dict) and isinstance(d2[key], dict): 
       # Don't pass result. 
       new_result = {} 
       new_keys(d1[key], d2[key],new_result) 
       # If new_result is not empty 
       if new_result: 
        result[key] = new_result 
      else: 
       if d1_val != d2[key]: 
        if not result.has_key('added'): 
         result['changed'] = {} 
         result['changed'][key] = d2[key] 
        else: 
         result['changed'][key] = d2[key] 
    for key, d2_val in d2.iteritems(): 
     if key not in d1: 
      if not result.has_key('added'): 
       result['added'] = {} 
       result['added'][key] = d2_val 
      else: 
       result['added'][key] = d2_val 
    return result 

with open("before.json") as data_file: 
    before = json.loads(data_file.read()) 

with open("after.json") as data_file: 
    after = json.loads(data_file.read()) 

pprint(new_keys(before,after)) 
関連する問題