如何比较具有相同元素的两个JSON对象的顺序是否相同?

我怎么能testing两个JSON对象在Python中是否相等,忽略列表的顺序?

例如 …

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"} ] } 

ab应该相等,即使"errors"列表的顺序不同。

如果你想要两个对象具有相同的元素,但是按照不同的顺序进行比较,那么显然要比较它们的sorting副本 – 例如,对于由JSONstringab表示的字典:

 import json a = json.loads(""" { "errors": [ {"error": "invalid", "field": "email"}, {"error": "required", "field": "name"} ], "success": false } """) b = json.loads(""" { "success": false, "errors": [ {"error": "required", "field": "name"}, {"error": "invalid", "field": "email"} ] } """) 
 >>> sorted(a.items()) == sorted(b.items()) False 

…但这是行不通的,因为在每种情况下,顶级词典的"errors"项目是一个具有相同元素的列表,而sorted()不会尝试sorting除了迭代的“顶”级。

为了解决这个问题,我们可以定义一个ordered函数,它将recursion地sorting它find的任何列表(并将字典转换为(key, value)对的列表,以便它们可以订购):

 def ordered(obj): if isinstance(obj, dict): return sorted((k, ordered(v)) for k, v in obj.items()) if isinstance(obj, list): return sorted(ordered(x) for x in obj) else: return obj 

如果我们将这个函数应用到ab ,结果比较相等:

 >>> ordered(a) == ordered(b) True 

另一种方法是使用json.dumps(X, sort_keys=True)选项:

 import json a, b = json.dumps(a, sort_keys=True), json.dumps(b, sort_keys=True) a == b # a normal string comparison 

这适用于嵌套字典和列表。

将它们解码并将它们作为mgilson注释进行比较。

只要键和值匹配,顺序对字典无关紧要。 (Python中没有词典)

 >>> {'a': 1, 'b': 2} == {'b': 2, 'a': 1} True 

但是秩序在列表中很重要; sorting将解决列表的问题。

 >>> [1, 2] == [2, 1] False >>> [1, 2] == sorted([2, 1]) True 

 >>> a = '{"errors": [{"error": "invalid", "field": "email"}, {"error": "required", "field": "name"}], "success": false}' >>> b = '{"errors": [{"error": "required", "field": "name"}, {"error": "invalid", "field": "email"}], "success": false}' >>> a, b = json.loads(a), json.loads(b) >>> a['errors'].sort() >>> b['errors'].sort() >>> a == b True 

上面的例子将适用于问题中的JSON。 有关一般解决scheme,请参见Zero Piraeus的答案。