【发布时间】: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