在嵌套字典中追加和管理密钥

时间:2016-05-02 13:15:50

标签: python python-2.7 loops dictionary

我编写了一个脚本(在堆栈溢出的帮助下)来区分两个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))

新输出 - 请注意,它只会看到第一个更改...我相信它是因为我将字典覆盖为空字符...但是如何初始化它?

{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': []}}}}}}

1 个答案:

答案 0 :(得分: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))