[英]How to compare two json objects to check what has changed?
我有两个 json 对象如下:
json.json
{
"access_points": [
{
"ssid": "MyAP",
"snr": 63,
"channel": 11
},
{
"ssid": "YourAP",
"snr": 42,
"channel": 1
},
{
"ssid": "HisAP",
"snr": 54,
"channel": 6
}
]
}
json_.json
{
"access_points": [
{
"ssid": "MyAP",
"snr": 82,
"channel": 11
},
{
"ssid": "YourAP",
"snr": 42,
"channel": 6
},
{
"ssid": "HerAP",
"snr": 71,
"channel": 1
}
]
}
正如您在上面看到的,这些值发生了一些变化,如下所示:
我需要跟踪以上内容,我预期的 output 应该是:
Following items have changed: ==========================
1. MyAP’s SNR has changed from 63 to 82
2. YourAP’s channel has changed from 1 to 6
3. HisAP is removed from the list
4. HerAP is added to the list with SNR 71 and channel 1
========================================================
这就是我一直在尝试比较键的内容,但我对如何比较每个嵌套值感到困惑:
def checkIfEquals(obj):
if isinstance(obj, dict):
return sorted((k, checkIfEquals(v)) for k, v in obj.items())
if isinstance(obj, list):
return sorted(checkIfEquals(x) for x in obj)
else:
return obj
def test():
# JSON string
with open('/Users/jananath/Desktop/Int/tmp/json.json') as data_file:
one = json.load(data_file)
with open('/Users/jananath/Desktop/Int/tmp/json_.json') as data_file:
two = json.load(data_file)
areTheytheSame = checkIfEquals(one) == checkIfEquals(two)
if areTheytheSame:
print("Same")
else:
for key in two.keys():
value = two[key]
if key not in one:
print("found new key {0} with value {1}".format(key, value))
else:
#check if values are not same
if one[key] != value: print("for key %s values are different" % key)
有人可以帮忙吗?
我的代码仅适用于您在示例数据中显示的结构。
至于我checkIfEquals
是无用的,因为它不会创建我可以用来获取详细差异的结构。 为此,它仍然需要使用原始数据。 这样我就可以简单地在开始时设置the_same = True
并逐个比较元素,当有差异时显示它并设置the_same = True
。 如果最后我有the_same = False
那么我可以打印The same
但是何时将access_points
作为字典获取很简单
one: {'MyAP': {'snr': 63, 'channel': 11}, 'YourAP': {'snr': 42, 'channel': 1}, 'HisAP': {'snr': 54, 'channel': 6}}
two: {'MyAP': {'snr': 82, 'channel': 11}, 'YourAP': {'snr': 42, 'channel': 6}, 'HerAP': {'snr': 71, 'channel': 1}}
因为现在我可以获得所有密钥( ssid
)并转换为set()
并检查添加了哪些,删除了哪些以及两者都包含了哪些。
one_keys = set(one.keys())
two_keys = set(two.keys())
only_one = sorted(one_keys - two_keys)
only_two = sorted(two_keys - one_keys)
both = sorted(one_keys & two_keys)
稍后我可以使用only_one
来显示删除的项目, only_two
来显示添加的项目,并且both
来比较snr
, channel
和显示差异。
完整的工作代码:
one = {
"access_points": [
{
"ssid": "MyAP",
"snr": 63,
"channel": 11
},
{
"ssid": "YourAP",
"snr": 42,
"channel": 1
},
{
"ssid": "HisAP",
"snr": 54,
"channel": 6
}
]
}
two = {
"access_points": [
{
"ssid": "MyAP",
"snr": 82,
"channel": 11
},
{
"ssid": "YourAP",
"snr": 42,
"channel": 6
},
{
"ssid": "HerAP",
"snr": 71,
"channel": 1
}
]
}
# --- functions ---
def get_access_points(data):
result = {}
for item in data["access_points"]:
name = item['ssid']
item.pop('ssid')
result[name] = item
return result
# --- main ---
one = get_access_points(one)
two = get_access_points(two)
print('one:', one)
print('two:', two)
print('---')
one_keys = set(one.keys())
two_keys = set(two.keys())
only_one = sorted(one_keys - two_keys)
only_two = sorted(two_keys - one_keys)
both = sorted(one_keys & two_keys)
print('only_one:', only_one)
print('only_two:', only_two)
print('both :', both)
print('---')
the_same = True
for key in both:
item1 = one[key]
item2 = two[key]
if item1["snr"] != item2["snr"]:
print(f'{key:10} | changed | SNR from {item1["snr"]} to {item2["snr"]}')
the_same = False
if item1["channel"] != item2["channel"]:
print(f'{key:10} | changed | CHANNEL from {item1["channel"]} to {item2["channel"]}')
the_same = False
for key in only_one:
item = one[key]
print(f'{key:10} | removed | with SNR {item["snr"]} and CHANNEL {item["channel"]}')
the_same = False
for key in only_two:
item = two[key]
print(f'{key:10} | added | with SNR {item["snr"]} and CHANNEL {item["channel"]}')
the_same = False
if the_same:
print('The same')
结果:
one: {'MyAP': {'snr': 63, 'channel': 11}, 'YourAP': {'snr': 42, 'channel': 1}, 'HisAP': {'snr': 54, 'channel': 6}}
two: {'MyAP': {'snr': 82, 'channel': 11}, 'YourAP': {'snr': 42, 'channel': 6}, 'HerAP': {'snr': 71, 'channel': 1}}
---
only_one: ['HisAP']
only_two: ['HerAP']
both : ['MyAP', 'YourAP']
---
MyAP | changed | SNR from 63 to 82
YourAP | changed | CHANNEL from 1 to 6
HisAP | removed | with SNR 54 and CHANNEL 6
HerAP | added | with SNR 71 and CHANNEL 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.