สำหรับสอง 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()))
ให้ผลลัพธ์ที่ผิดคือเท็จ
ดังนั้นฉันจึงสร้าง 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):
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))
ซึ่งทำให้ฉันได้ผลลัพธ์ที่คาดหวังที่ถูกต้อง!
ตรรกะค่อนข้างง่าย:
หากวัตถุเป็นประเภท 'รายการ' ให้เปรียบเทียบแต่ละรายการของรายการแรกกับรายการของรายการที่สองจนกว่าจะพบและหากไม่พบรายการหลังจากผ่านรายการที่สองแล้ว 'พบ' จะเป็น = เท็จ ค่า 'found' จะถูกส่งกลับ
ไม่เช่นนั้นถ้าวัตถุที่จะเปรียบเทียบเป็นประเภท 'dict' ให้เปรียบเทียบค่าที่มีอยู่สำหรับคีย์ทั้งหมดในวัตถุทั้งสอง (ทำการเปรียบเทียบแบบวนซ้ำ)
หรือเรียกง่ายๆว่า obj1 == obj2 โดยค่าเริ่มต้นทำงานได้ดีสำหรับออบเจ็กต์ของสตริงและตัวเลขและสำหรับeq () เหล่านั้นถูกกำหนดอย่างเหมาะสม
(โปรดทราบว่าอัลกอริทึมสามารถปรับปรุงเพิ่มเติมได้โดยการลบรายการที่พบใน object2 เพื่อไม่ให้รายการถัดไปของ object1 เปรียบเทียบตัวเองกับรายการที่พบใน object2 แล้ว)