如何在python中测试两个JSON对象是否相等,而不考虑列表的顺序?
比如......
JSON文档a:
{
"errors": [
{"error": "invalid", "field": "email"},
{"error": "required", "field": "name"}
],
"success": false
}
JSON文档B:
{
"success": false,
"errors": [
{"error": "required", "field": "name"},
{"error": "invalid", "field": "email"}
]
}
即使"errors"
列表的顺序不同,a
和b
也应该比较为相等。
9条答案
按热度按时间qyuhtwio1#
如果希望元素相同但顺序不同的两个对象比较起来是相等的,那么很明显要做的就是比较它们的排序副本--例如,对于JSON字符串
a
和b
表示的字典:第一个
...但这是行不通的,因为在每种情况下,顶层dict的
"errors"
项都是一个列表,其中相同的元素具有不同的顺序,并且sorted()
不会尝试对除可迭代对象的“顶层”之外的任何内容进行排序。为了解决这个问题,我们可以定义一个
ordered
函数,它将递归地对它找到的任何列表进行排序(并将字典转换为(key, value)
对的列表,以便它们是可排序的):如果我们将此函数应用于
a
和b
,则结果比较相等:zbwhf8kr2#
另一种方法是使用
json.dumps(X, sort_keys=True)
选项:这适用于嵌套词典和列表。
cwdobuhd3#
解码它们,并比较它们作为mgilson评论。
只要键和值匹配,字典的顺序并不重要。(Python中字典没有顺序)
但顺序在列表中很重要;排序将解决列表的问题。
第一次
上面的例子适用于问题中的JSON。关于通用的解决方案,请参见Zero比雷埃夫斯的答案。
g6ll5ycj4#
是的!您可以使用jycm
用于更复杂的示例(深层结构中的值更改)
其结果可以被呈现为x1c 0d1x
wnavrhmk5#
对于以下两个字典'dictWithListsInValue'和'reorderedDictWithReorderedListsInValue',它们只是彼此的重新排序版本
给了我错误的结果,即错误。
所以我创建了自己的cutstom ObjectComparator,如下所示:
这给了我正确的预期输出!
逻辑很简单:
如果对象的类型为'list',则将第一个列表中的每个项与第二个列表中的项进行比较,直到找到为止,如果在遍历第二个列表后没有找到项,则'found'将为= false。返回'found'值
否则,如果要比较的对象是“dict”类型,则比较两个对象中所有相应键的值。(执行递归比较)
否则,只需调用obj 1 == obj 2。默认情况下,它可以很好地处理字符串和数字对象,并且对这些对象适当地定义了eq()。
(Note该算法可以通过移除在object 2中找到的项来进一步改进,使得object 1的下一项将不将其自身与已经在object 2中找到的项进行比较)
af7jpaap6#
您可以编写自己的equals函数:
a == b
,则基元相等因为处理的是json,所以将使用标准的python类型:
dict
、list
等,因此您可以执行硬类型检查if type(obj) == 'dict':
等。粗略示例(未测试):
o7jaxewo7#
对于其他想要调试两个JSON对象(通常有一个reference和一个target)的人,这里有一个你可以使用的解决方案。它将列出从target到reference的不同/不匹配对象的“path”。
level
选项用于选择要查看的深度。show_variables
选项可以打开以显示相关变量。nfeuvbwi8#
导入json
API响应示例
一些JSON:
x = '{“姓名”:“约翰”,“年龄”:30,“城市”:“纽约”}'
parse x json to Python字典:
y = json.载荷(x)
访问Python字典打印(y[“age”])
需要json作为字典
thisdict = {“姓名”:“约翰”,“年龄”:30,“城市”:“纽约”}打印(thisdict)
访问Python字典
印刷品
比较两个访问Python字典
如果此命令== y:print(“dict 1等于dict 2”)否则:打印(“dict 1不等于dict 2”)
pgky5nke9#
使用KnoDL,它可以在不Map字段的情况下匹配数据。