【问题标题】:Appending and managing keys in nested dictionaries在嵌套字典中附加和管理键
【发布时间】:2016-05-02 13:15:50
【问题描述】:

我编写了一个脚本(借助堆栈溢出)来比较两个 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': []}}}}}}

【问题讨论】:

  • 你发布的第二个文件不是有效的json/python,你有一些额外的")"
  • @luke14free 这不是一个文件。这是一个手动输入的示例,用于直观表示我的目标。

标签: python python-2.7 loops dictionary


【解决方案1】:

想通了——

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))

【讨论】:

    猜你喜欢
    • 2018-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    • 1970-01-01
    • 2019-09-20
    • 2021-02-22
    • 2022-08-12
    相关资源
    最近更新 更多