다음 두 dicts 'dictWithListsInValue'및 'reorderedDictWithReorderedListsInValue'의 경우 단순히 서로의 순서가 변경된 버전입니다.
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
나에게 잘못된 결과 즉, 거짓을 주었다.
그래서 다음과 같이 내 자신의 cutstom ObjectComparator를 만들었습니다.
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
올바른 예상 결과를 얻었습니다!
논리는 매우 간단합니다.
객체가 'list'유형이면 found 될 때까지 첫 번째 목록의 각 항목을 두 번째 목록의 항목과 비교하고 두 번째 목록을 통과 한 후에도 항목을 찾을 수 없으면 'found'는 = false가됩니다. '발견 된'값이 반환됩니다.
그렇지 않으면 비교할 개체가 'dict'유형 인 경우 두 개체의 모든 각 키에 대해 존재하는 값을 비교합니다. (재귀 비교가 수행됨)
그렇지 않으면 단순히 obj1 == obj2를 호출하십시오. 기본적으로 문자열과 숫자의 객체에 대해 잘 작동하며 eq ()가 적절하게 정의되어 있습니다.
(object2에서 찾은 항목을 제거하여 알고리즘을 더욱 향상시킬 수 있으므로 object1의 다음 항목은 object2에서 이미 찾은 항목과 비교되지 않습니다.)