Hướng dẫn how to compare nested dictionary in python - cách so sánh từ điển lồng nhau trong python

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

Hướng dẫn how to compare nested dictionary in python - cách so sánh từ điển lồng nhau trong python

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

Hướng dẫn how to compare nested dictionary in python - cách so sánh từ điển lồng nhau trong python

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: https://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

Hướng dẫn how to compare nested dictionary in python - cách so sánh từ điển lồng nhau trong python

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)

Hướng dẫn how to compare nested dictionary in python - cách so sánh từ điển lồng nhau trong python

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

Hướng dẫn how to compare nested dictionary in python - cách so sánh từ điển lồng nhau trong python

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

Hướng dẫn how to compare nested dictionary in python - cách so sánh từ điển lồng nhau trong python

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

Hướng dẫn how to compare nested dictionary in python - cách so sánh từ điển lồng nhau trong python

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

Hướng dẫn how to compare nested dictionary in python - cách so sánh từ điển lồng nhau trong python

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])
2

Example:

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])
3

Output:

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

Hướng dẫn how to compare nested dictionary in python - cách so sánh từ điển lồng nhau trong python

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])
5

Thí 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

Hướng dẫn how to compare nested dictionary in python - cách so sánh từ điển lồng nhau trong python

1

Chúng ta có thể so sánh 2 từ điển trong Python không?

Sử dụng == Toán tử để so sánh hai từ điển ở đây, chúng tôi đang sử dụng toán tử so sánh bình đẳng trong Python để so sánh hai từ điển cho dù cả hai có cùng một cặp giá trị khóa hay không. Here we are using the equality comparison operator in Python to compare two dictionaries whether both have the same key value pairs or not.

Bạn có thể sử dụng == trên từ điển trong Python không?

Theo tài liệu Python, bạn thực sự có thể sử dụng toán tử == trên từ điển.you can indeed use the == operator on dictionaries.

Làm cách nào để so sánh từ điển trong Python 3?

Sự mô tả.Phương thức cmp () so sánh hai từ điển dựa trên khóa và giá trị ..
Cú pháp.Sau đây là cú pháp cho phương pháp cmp () - cmp (dict1, dict2).
Thông số.Dict1 - Đây là từ điển đầu tiên được so sánh với Dict2.....
Giá trị trả về.....
Thí dụ.....
Result..

Làm thế nào bạn có thể biết nếu hai từ điển là giống nhau?

Sử dụng == Toán tử để kiểm tra xem các từ điển có bằng nhau không, bạn có thể tạo từ điển với bất kỳ phương thức nào được xác định trong Python và sau đó so sánh chúng bằng toán tử ==.Nó sẽ trả về sự thật các từ điển là bằng và sai nếu không. You can create the dictionaries with any of the methods defined in Python and then compare them using the == operator. It will return True the dictionaries are equals and False if not.