Pour les deux dictionnaires suivants 'dictWithListsInValue' et 'reorderedDictWithReorderedListsInValue' qui sont simplement des versions réorganisées l'une de l'autre
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
m'a donné un mauvais résultat, c'est-à-dire faux.
J'ai donc créé mon propre ObjectComparator cutstom comme ceci:
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
ce qui m'a donné la sortie correcte attendue!
La logique est assez simple:
Si les objets sont de type «liste», comparez chaque élément de la première liste avec les éléments de la deuxième liste jusqu'à ce qu'ils soient trouvés, et si l'élément n'est pas trouvé après avoir parcouru la deuxième liste, alors «trouvé» serait = faux. La valeur 'found' est renvoyée
Sinon, si les objets à comparer sont de type «dict», comparez les valeurs présentes pour toutes les clés respectives dans les deux objets. (Une comparaison récursive est effectuée)
Sinon, appelez simplement obj1 == obj2. Par défaut, cela fonctionne bien pour l'objet de chaînes et de nombres et pour ceux-ci, eq () est défini de manière appropriée.
(Notez que l'algorithme peut encore être amélioré en supprimant les éléments trouvés dans object2, de sorte que l'élément suivant de object1 ne se compare pas avec les éléments déjà trouvés dans l'objet2)