So sánh 2 từ điển bằng cách sử dụng đệ quy:
Được chỉnh sửa cho Python 3 [cũng hoạt động cho Python 2]:
d1= {'a':{'b':{'cs':10},'d':{'cs':20}}}
d2= {'a':{'b':{'cs':30} ,'d':{'cs':20}},'newa':{'q':{'cs':50}}}
def findDiff[d1, d2, path=""]:
for k in d1:
if k in d2:
if type[d1[k]] is dict:
findDiff[d1[k],d2[k], "%s -> %s" % [path, k] if path else k]
if d1[k] != d2[k]:
result = [ "%s: " % path, " - %s : %s" % [k, d1[k]] , " + %s : %s" % [k, d2[k]]]
print["\n".join[result]]
else:
print ["%s%s as key not in d2\n" % ["%s: " % path if path else "", k]]
print["comparing d1 to d2:"]
findDiff[d1,d2]
print["comparing d2 to d1:"]
findDiff[d2,d1]
Python 2 Câu trả lời cũ:
def findDiff[d1, d2, path=""]:
for k in d1:
if [k not in d2]:
print [path, ":"]
print [k + " as key not in d2", "\n"]
else:
if type[d1[k]] is dict:
if path == "":
path = k
else:
path = path + "->" + k
findDiff[d1[k],d2[k], path]
else:
if d1[k] != d2[k]:
print [path, ":"]
print [" - ", k," : ", d1[k]]
print [" + ", k," : ", d2[k]]
Output:
comparing d1 to d2:
a -> b:
- cs : 10
+ cs : 30
comparing d2 to d1:
a -> b:
- cs : 30
+ cs : 10
Đã trả lời ngày 3 tháng 12 năm 2014 lúc 7:41Dec 3, 2014 at 7:41
Venpavenpavenpa
4.17820 Huy hiệu bạc23 Huy hiệu đồng20 silver badges23 bronze badges
1
Mã người dùng đã sửa đổi để làm cho nó thậm chí còn tốt hơn
d1= {'as': 1, 'a':
{'b':
{'cs':10,
'qqq': {'qwe':1}
},
'd': {'csd':30}
}
}
d2= {'as': 3, 'a':
{'b':
{'cs':30,
'qqq': 123
},
'd':{'csd':20}
},
'newa':
{'q':
{'cs':50}
}
}
def compare_dictionaries[dict_1, dict_2, dict_1_name, dict_2_name, path=""]:
"""Compare two dictionaries recursively to find non mathcing elements
Args:
dict_1: dictionary 1
dict_2: dictionary 2
Returns:
"""
err = ''
key_err = ''
value_err = ''
old_path = path
for k in dict_1.keys[]:
path = old_path + "[%s]" % k
if not dict_2.has_key[k]:
key_err += "Key %s%s not in %s\n" % [dict_2_name, path, dict_2_name]
else:
if isinstance[dict_1[k], dict] and isinstance[dict_2[k], dict]:
err += compare_dictionaries[dict_1[k],dict_2[k],'d1','d2', path]
else:
if dict_1[k] != dict_2[k]:
value_err += "Value of %s%s [%s] not same as %s%s [%s]\n"\
% [dict_1_name, path, dict_1[k], dict_2_name, path, dict_2[k]]
for k in dict_2.keys[]:
path = old_path + "[%s]" % k
if not dict_1.has_key[k]:
key_err += "Key %s%s not in %s\n" % [dict_2_name, path, dict_1_name]
return key_err + value_err + err
a = compare_dictionaries[d1,d2,'d1','d2']
print a
Output:
Key d2[newa] not in d1
Value of d1[as] [1] not same as d2[as] [3]
Value of d1[a][b][cs] [10] not same as d2[a][b][cs] [30]
Value of d1[a][b][qqq] [{'qwe': 1}] not same as d2[a][b][qqq] [123]
Value of d1[a][d][csd] [30] not same as d2[a][d][csd] [20]
Đã trả lời ngày 28 tháng 1 năm 2016 lúc 15:07Jan 28, 2016 at 15:07
MohitcmohitcMohitC
4.2352 Huy hiệu vàng30 Huy hiệu bạc52 Huy hiệu Đồng2 gold badges30 silver badges52 bronze badges
2
Tại sao không sử dụng Thư viện DeepDiff.
Xem nó tại: //github.com/sperman/deepdiff
>>> from deepdiff import DeepDiff
>>> t1 = {1:1, 3:3, 4:4}
>>> t2 = {1:1, 3:3, 5:5, 6:6}
>>> ddiff = DeepDiff[t1, t2]
>>> print[ddiff]
{'dictionary_item_added': {'root[5]', 'root[6]'}, 'dictionary_item_removed': {'root[4]'}}
Tất nhiên nó mạnh hơn, kiểm tra tài liệu để biết thêm.
Đã trả lời ngày 24 tháng 11 năm 2020 lúc 11:06Nov 24, 2020 at 11:06
GXMADGXMADgxmad
1.2322 Huy hiệu vàng19 Huy hiệu bạc24 Huy hiệu đồng2 gold badges19 silver badges24 bronze badges
0
Điều này sẽ cung cấp những gì bạn cần với các chức năng hữu ích:
Cho Python 2.7
def isDict[obj]:
return obj.__class__.__name__ == 'dict'
def containsKeyRec[vKey, vDict]:
for curKey in vDict:
if curKey == vKey or [isDict[vDict[curKey]] and containsKeyRec[vKey, vDict[curKey]]]:
return True
return False
def getValueRec[vKey, vDict]:
for curKey in vDict:
if curKey == vKey:
return vDict[curKey]
elif isDict[vDict[curKey]] and getValueRec[vKey, vDict[curKey]]:
return containsKeyRec[vKey, vDict[curKey]]
return None
d1= {'a':{'b':{'cs':10},'d':{'cs':20}}}
d2= {'a':{'b':{'cs':30} ,'d':{'cs':20}},'newa':{'q':{'cs':50}}}
for key in d1:
if containsKeyRec[key, d2]:
print "dict d2 contains key: " + key
d2Value = getValueRec[key, d2]
if d1[key] == d2Value:
print "values are equal, d1: " + str[d1[key]] + ", d2: " + str[d2Value]
else:
print "values are not equal, d1: " + str[d1[key]] + ", d2: " + str[d2Value]
else:
print "dict d2 does not contain key: " + key
Cho Python 3 [hoặc cao hơn]:
def id_dict[obj]:
return obj.__class__.__name__ == 'dict'
def contains_key_rec[v_key, v_dict]:
for curKey in v_dict:
if curKey == v_key or [id_dict[v_dict[curKey]] and contains_key_rec[v_key, v_dict[curKey]]]:
return True
return False
def get_value_rec[v_key, v_dict]:
for curKey in v_dict:
if curKey == v_key:
return v_dict[curKey]
elif id_dict[v_dict[curKey]] and get_value_rec[v_key, v_dict[curKey]]:
return contains_key_rec[v_key, v_dict[curKey]]
return None
d1 = {'a': {'b': {'cs': 10}, 'd': {'cs': 20}}}
d2 = {'a': {'b': {'cs': 30}, 'd': {'cs': 20}}, 'newa': {'q': {'cs': 50}}}
for key in d1:
if contains_key_rec[key, d2]:
d2_value = get_value_rec[key, d2]
if d1[key] == d2_value:
print["values are equal, d1: " + str[d1[key]] + ", d2: " + str[d2_value]]
pass
else:
print["values are not equal:\n"
"list1: " + str[d1[key]] + "\n" +
"list2: " + str[d2_value]]
else:
print["dict d2 does not contain key: " + key]
Người ven sông
4826 Huy hiệu bạc17 Huy hiệu đồng6 silver badges17 bronze badges
Đã trả lời ngày 3 tháng 12 năm 2014 lúc 8:20Dec 3, 2014 at 8:20
lahu89lahu89lahu89
3531 Huy hiệu bạc11 Huy hiệu đồng1 silver badge11 bronze badges
Đối với Python 3 trở lên, mã để so sánh bất kỳ dữ liệu nào.
def do_compare[data1, data2, data1_name, data2_name, path=""]:
if operator.eq[data1, data2] and not path:
log.info["Both data have same content"]
else:
if isinstance[data1, dict] and isinstance[data2, dict]:
compare_dict[data1, data2, data1_name, data2_name, path]
elif isinstance[data1, list] and isinstance[data2, list]:
compare_list[data1, data2, data1_name, data2_name, path]
else:
if data1 != data2:
value_err = "Value of %s%s [%s] not same as %s%s [%s]\n"\
% [data1_name, path, data1, data2_name, path, data2]
print [value_err]
# findDiff[data1, data2]
def compare_dict[data1, data2, data1_name, data2_name, path]:
old_path = path
for k in data1.keys[]:
path = old_path + "[%s]" % k
if k not in data2:
key_err = "Key %s%s not in %s\n" % [data1_name, path, data2_name]
print [key_err]
else:
do_compare[data1[k], data2[k], data1_name, data2_name, path]
for k in data2.keys[]:
path = old_path + "[%s]" % k
if k not in data1:
key_err = "Key %s%s not in %s\n" % [data2_name, path, data1_name]
print [key_err]
def compare_list[data1, data2, data1_name, data2_name, path]:
data1_length = len[data1]
data2_length = len[data2]
old_path = path
if data1_length != data2_length:
value_err = "No: of items in %s%s [%s] not same as %s%s [%s]\n"\
% [data1_name, path, data1_length, data2_name, path, data2_length]
print [value_err]
for index, item in enumerate[data1]:
path = old_path + "[%s]" % index
try:
do_compare[data1[index], data2[index], data1_name, data2_name, path]
except IndexError:
pass
Đã trả lời ngày 23 tháng 7 năm 2019 lúc 6:05Jul 23, 2019 at 6:05
Thêm một phiên bản thêm một số khả năng khác:
- có thể so sánh các danh sách và danh sách giống như JSON được lồng tùy ý
- Cho phép bạn chỉ định các khóa để bỏ qua [ví dụ: trong các bài kiểm tra đơn vị flaky]
- Cho phép bạn chỉ định các khóa với các giá trị số sẽ được đối xử bằng nhau miễn là chúng nằm trong một tỷ lệ nhất định của nhau
Nếu bạn xác định chức năng
def findDiff[d1, d2, path=""]:
for k in d1:
if [k not in d2]:
print [path, ":"]
print [k + " as key not in d2", "\n"]
else:
if type[d1[k]] is dict:
if path == "":
path = k
else:
path = path + "->" + k
findDiff[d1[k],d2[k], path]
else:
if d1[k] != d2[k]:
print [path, ":"]
print [" - ", k," : ", d1[k]]
print [" + ", k," : ", d2[k]]
8 như bên dưới và gọi nó theo ví dụ của @rkatkam, bạn sẽ nhận được:>>> deep_diff[d1, d2]
{'newa': [None, {'q': {'cs': 50}}], 'a': {'b': {'cs': [10, 30]}}}
Đây là định nghĩa chức năng:
def findDiff[d1, d2, path=""]:
for k in d1:
if [k not in d2]:
print [path, ":"]
print [k + " as key not in d2", "\n"]
else:
if type[d1[k]] is dict:
if path == "":
path = k
else:
path = path + "->" + k
findDiff[d1[k],d2[k], path]
else:
if d1[k] != d2[k]:
print [path, ":"]
print [" - ", k," : ", d1[k]]
print [" + ", k," : ", d2[k]]
0Đã trả lời ngày 24 tháng 3 năm 2021 lúc 2:00Mar 24, 2021 at 2:00
Thêm một giải pháp không thu hồi.
def findDiff[d1, d2, path=""]:
for k in d1:
if [k not in d2]:
print [path, ":"]
print [k + " as key not in d2", "\n"]
else:
if type[d1[k]] is dict:
if path == "":
path = k
else:
path = path + "->" + k
findDiff[d1[k],d2[k], path]
else:
if d1[k] != d2[k]:
print [path, ":"]
print [" - ", k," : ", d1[k]]
print [" + ", k," : ", d2[k]]
1Đã trả lời ngày 10 tháng 1 năm 2020 lúc 14:04Jan 10, 2020 at 14:04
Arran Duffarran DuffArran Duff
1.1061 huy hiệu vàng9 Huy hiệu bạc21 Huy hiệu đồng1 gold badge9 silver badges21 bronze badges
Tôi đã không thích nhiều câu trả lời mà tôi đã tìm thấy trên nhiều chủ đề ... rất nhiều trong số chúng khuyên bạn nên sử dụng
def findDiff[d1, d2, path=""]:
for k in d1:
if [k not in d2]:
print [path, ":"]
print [k + " as key not in d2", "\n"]
else:
if type[d1[k]] is dict:
if path == "":
path = k
else:
path = path + "->" + k
findDiff[d1[k],d2[k], path]
else:
if d1[k] != d2[k]:
print [path, ":"]
print [" - ", k," : ", d1[k]]
print [" + ", k," : ", d2[k]]
9 rất mạnh không hiểu tôi nhưng nó không cho tôi đầu ra mà tôi mong muốn không chỉ là một chuỗi của các khác biệt, hoặc một từ điển trông lạ mới được xây dựng với các khóa mới được thu thập từ các khóa lồng của bản gốc ... nhưng thực sự trả về một từ điển thực với các khóa gốc và giá trị delta.Trường hợp sử dụng của tôi cho điều này là gửi tải trọng nhỏ hơn hoặc không có nếu không có sự khác biệt so với mạng MQTT.
Soluton tôi tìm thấy đã bị đánh cắp một phần từ liên kết này, tuy nhiên đã sửa đổi nó để cho tôi đồng bằng. Sau đó, tôi đệ trình nó, gọi lại
comparing d1 to d2:
a -> b:
- cs : 10
+ cs : 30
comparing d2 to d1:
a -> b:
- cs : 30
+ cs : 10
0 nếu nó được lồng để xây dựng từ điển Diff cuối cùng. Nó hóa ra đơn giản hơn nhiều so với nhiều ví dụ ngoài kia. FYI nó không quan tâm đến việc sắp xếp.Giải pháp của tôi:
def findDiff[d1, d2, path=""]:
for k in d1:
if [k not in d2]:
print [path, ":"]
print [k + " as key not in d2", "\n"]
else:
if type[d1[k]] is dict:
if path == "":
path = k
else:
path = path + "->" + k
findDiff[d1[k],d2[k], path]
else:
if d1[k] != d2[k]:
print [path, ":"]
print [" - ", k," : ", d1[k]]
print [" + ", k," : ", d2[k]]
2Example:
def findDiff[d1, d2, path=""]:
for k in d1:
if [k not in d2]:
print [path, ":"]
print [k + " as key not in d2", "\n"]
else:
if type[d1[k]] is dict:
if path == "":
path = k
else:
path = path + "->" + k
findDiff[d1[k],d2[k], path]
else:
if d1[k] != d2[k]:
print [path, ":"]
print [" - ", k," : ", d1[k]]
print [" + ", k," : ", d2[k]]
3Output:
def findDiff[d1, d2, path=""]:
for k in d1:
if [k not in d2]:
print [path, ":"]
print [k + " as key not in d2", "\n"]
else:
if type[d1[k]] is dict:
if path == "":
path = k
else:
path = path + "->" + k
findDiff[d1[k],d2[k], path]
else:
if d1[k] != d2[k]:
print [path, ":"]
print [" - ", k," : ", d1[k]]
print [" + ", k," : ", d2[k]]
4Đã trả lời ngày 10 tháng 11 năm 2021 lúc 5:19Nov 10, 2021 at 5:19
Dung dịch
def findDiff[d1, d2, path=""]:
for k in d1:
if [k not in d2]:
print [path, ":"]
print [k + " as key not in d2", "\n"]
else:
if type[d1[k]] is dict:
if path == "":
path = k
else:
path = path + "->" + k
findDiff[d1[k],d2[k], path]
else:
if d1[k] != d2[k]:
print [path, ":"]
print [" - ", k," : ", d1[k]]
print [" + ", k," : ", d2[k]]
5Thí dụ
def findDiff[d1, d2, path=""]:
for k in d1:
if [k not in d2]:
print [path, ":"]
print [k + " as key not in d2", "\n"]
else:
if type[d1[k]] is dict:
if path == "":
path = k
else:
path = path + "->" + k
findDiff[d1[k],d2[k], path]
else:
if d1[k] != d2[k]:
print [path, ":"]
print [" - ", k," : ", d1[k]]
print [" + ", k," : ", d2[k]]
6Đầu ra
def findDiff[d1, d2, path=""]:
for k in d1:
if [k not in d2]:
print [path, ":"]
print [k + " as key not in d2", "\n"]
else:
if type[d1[k]] is dict:
if path == "":
path = k
else:
path = path + "->" + k
findDiff[d1[k],d2[k], path]
else:
if d1[k] != d2[k]:
print [path, ":"]
print [" - ", k," : ", d1[k]]
print [" + ", k," : ", d2[k]]
7Đã trả lời ngày 26 tháng 2 lúc 11:44Feb 26 at 11:44
1