Für die folgenden zwei Diktate 'dictWithListsInValue' und 'reorderedDictWithReorderedListsInValue', die einfach neu geordnete Versionen voneinander sind
dictObj = {"foo": "bar", "john": "doe"}
reorderedDictObj = {"john": "doe", "foo": "bar"}
dictObj2 = {"abc": "def"}
dictWithListsInValue = {'A': [{'X': [dictObj2, dictObj]}, {'Y': 2}], 'B': dictObj2}
reorderedDictWithReorderedListsInValue = {'B': dictObj2, 'A': [{'Y': 2}, {'X': [reorderedDictObj, dictObj2]}]}
a = {"L": "M", "N": dictWithListsInValue}
b = {"L": "M", "N": reorderedDictWithReorderedListsInValue}
print(sorted(a.items()) == sorted(b.items())) # gives false
gab mir falsches Ergebnis dh falsch.
Also habe ich meinen eigenen cutstom ObjectComparator wie folgt erstellt:
def my_list_cmp(list1, list2):
if (list1.__len__() != list2.__len__()):
return False
for l in list1:
found = False
for m in list2:
res = my_obj_cmp(l, m)
if (res):
found = True
break
if (not found):
return False
return True
def my_obj_cmp(obj1, obj2):
if isinstance(obj1, list):
if (not isinstance(obj2, list)):
return False
return my_list_cmp(obj1, obj2)
elif (isinstance(obj1, dict)):
if (not isinstance(obj2, dict)):
return False
exp = set(obj2.keys()) == set(obj1.keys())
if (not exp):
# print(obj1.keys(), obj2.keys())
return False
for k in obj1.keys():
val1 = obj1.get(k)
val2 = obj2.get(k)
if isinstance(val1, list):
if (not my_list_cmp(val1, val2)):
return False
elif isinstance(val1, dict):
if (not my_obj_cmp(val1, val2)):
return False
else:
if val2 != val1:
return False
else:
return obj1 == obj2
return True
dictObj = {"foo": "bar", "john": "doe"}
reorderedDictObj = {"john": "doe", "foo": "bar"}
dictObj2 = {"abc": "def"}
dictWithListsInValue = {'A': [{'X': [dictObj2, dictObj]}, {'Y': 2}], 'B': dictObj2}
reorderedDictWithReorderedListsInValue = {'B': dictObj2, 'A': [{'Y': 2}, {'X': [reorderedDictObj, dictObj2]}]}
a = {"L": "M", "N": dictWithListsInValue}
b = {"L": "M", "N": reorderedDictWithReorderedListsInValue}
print(my_obj_cmp(a, b)) # gives true
das gab mir die richtige erwartete Ausgabe!
Logik ist ziemlich einfach:
Wenn die Objekte vom Typ 'Liste' sind, vergleichen Sie jedes Element der ersten Liste mit den Elementen der zweiten Liste, bis sie gefunden werden. Wenn das Element nach Durchlaufen der zweiten Liste nicht gefunden wird, ist 'gefunden' = falsch. Der Wert 'found' wird zurückgegeben
Andernfalls vergleichen Sie die Werte, die für alle jeweiligen Schlüssel in beiden Objekten vorhanden sind, wenn die zu vergleichenden Objekte vom Typ 'dict' sind. (Rekursiver Vergleich wird durchgeführt)
Andernfalls rufen Sie einfach obj1 == obj2 auf. Es funktioniert standardmäßig gut für das Objekt von Zeichenfolgen und Zahlen und für diese ist eq () entsprechend definiert.
(Beachten Sie, dass der Algorithmus weiter verbessert werden kann, indem die in Objekt2 gefundenen Elemente entfernt werden, sodass sich das nächste Element von Objekt1 nicht mit den bereits in Objekt2 gefundenen Elementen vergleicht.)