Aşağıdaki iki dikt için 'dictWithListsInValue' ve 'reorderedDictWithReorderedListsInValue' birbirlerinin basitçe yeniden sıralı sürümleri olan
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()))
bana yanlış sonuç verdi, yani yanlış.
Bu yüzden kendi cutstom ObjectComparator'ımı şöyle yarattım:
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):
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))
bu bana beklenen doğru çıktıyı verdi!
Mantık oldukça basit:
Nesneler 'liste' türündeyse, bulunana kadar birinci listenin her bir öğesini ikinci listenin öğeleriyle karşılaştırın ve öğe ikinci listeden geçtikten sonra bulunamazsa, o zaman "bulundu" = false olacaktır. 'bulunan' değeri döndürülür
Aksi takdirde, karşılaştırılacak nesneler 'dict' türündeyse, her iki nesnede de tüm ilgili anahtarlar için mevcut değerleri karşılaştırın. (Özyinelemeli karşılaştırma yapılır)
Aksi takdirde obj1 == obj2'yi çağırın. Varsayılan olarak dizelerin ve sayıların nesnesi için iyi çalışır ve bunlar için eq () uygun şekilde tanımlanır.
(Algoritmanın, object2'de bulunan öğeler kaldırılarak daha da geliştirilebileceğini, böylece object1'in sonraki öğesinin kendisini zaten object2'de bulunan öğelerle karşılaştırmayacağını unutmayın)