두 사전을 비교하고 (키, 값) 쌍이 같은지 확인


246

나는 두 개의 사전을 가지고 있지만 단순화를 위해 다음 두 가지를 취할 것입니다.

>>> x = dict(a=1, b=2)
>>> y = dict(a=2, b=2)

이제 각 key, value쌍의에 x해당하는 값이에 있는지 여부를 비교하고 싶습니다 y. 그래서 나는 이것을 썼다 :

>>> for x_values, y_values in zip(x.iteritems(), y.iteritems()):
        if x_values == y_values:
            print 'Ok', x_values, y_values
        else:
            print 'Not', x_values, y_values

그리고 a tuple가 반환 된 후 작동 하고 평등을 비교합니다.

내 질문 :

이 올바른지? 거기에 더 나은 이 작업을 수행하는 방법은? 속도가 빠를수록 코드 우아함에 대해 이야기하고 있습니다.

업데이트 : 나는 얼마나 많은 key, value쌍이 같은지 확인해야한다는 것을 잊어 버렸습니다 .



x == y는 true 여야합니다. REPL을 신속하게 체크인 할 수 있습니다. 참조하십시오 : docs.python.org/2/library/stdtypes.html#mapping-types-dict
Vikrant

답변:


179

두 사전에서 몇 개의 값이 일치하는지 알고 싶다면 다음과 같이 말해야합니다. :)

아마도 이런 식으로 뭔가 :

shared_items = {k: x[k] for k in x if k in y and x[k] == y[k]}
print len(shared_items)

1
dict 키에 list 요소가 있으면 같은 오류가 발생합니다. 내가 빠진 것이 아니라면 cmp가 더 나은 방법이라고 생각합니다.
돌연변이

@ 돌연변이 그것은 다른 문제입니다. list우선 키를 사용하여 사전을 작성할 수 없습니다 . x = {[1,2]: 2}실패합니다. 질문은 이미 유효합니다 dicts.
AnnanFay

@ annan : 잘못된 질문은 일반적인 것입니다. 질문 설명 의 는 이미 "유효한 dicts"입니다. 제목이 같지만 다른 "유효하지 않은"dict으로 새 질문을 게시하면 누군가가 중복 된 것으로 표시합니다. 다운 보팅.
ribamar

6
@ribamar 문제는 "두 사전을 비교하는 것입니다 ...]. 위의 list키가 있는 '잘못된 dict' 는 유효한 파이썬 코드가 아닙니다-dict 는 변경 불가능해야합니다. 따라서 사전을 비교하지 않습니다. 목록을 사전 키로 사용하려고하면 코드가 실행되지 않습니다. 비교할 객체가 없습니다. 이것은 입력 x = dict(23\;dfg&^*$^%$^$%^)한 다음 사전에서 비교가 작동하지 않는 방식을 불평하는 것과 같습니다 . 물론 작동하지 않습니다. 반면 팀의 의견은 변경 가능 values에 관한 것이므로 다른 문제라고 말한 이유는 무엇입니까?
AnnanFay

1
@MikeyE- set값을 해시 가능 dict해야하며 키를 해시 가능해야합니다. set(x.keys())키는 해시 가능해야하기 때문에 항상 작동하지만 set(x.values())해시 가능하지 않은 값에서는 실패합니다.
Tim Tisdall

173

당신이하고 싶은 것은 단순히 x==y

사전의 항목에는 순서가 없어야하므로 좋은 생각이 아닙니다. (동일한 사전, 다른 순서) [('a',1),('b',1)]와 비교할 수 있습니다 [('b',1), ('a',1)].

예를 들어 다음을 참조하십시오.

>>> x = dict(a=2, b=2,c=3, d=4)
>>> x
{'a': 2, 'c': 3, 'b': 2, 'd': 4}
>>> y = dict(b=2,c=3, d=4)
>>> y
{'c': 3, 'b': 2, 'd': 4}
>>> zip(x.iteritems(), y.iteritems())
[(('a', 2), ('c', 3)), (('c', 3), ('b', 2)), (('b', 2), ('d', 4))]

차이점은 하나의 항목이지만 알고리즘 에 따라 모든 항목이 다릅니다.


@ THC4k, 언급하지 않아서 죄송합니다. 그러나 두 사전에서 몇 개의 값이 일치하는지 확인해야합니다.
user225312

내 업데이트에 따라 내 방식이 여전히 올바르지 않습니까?
user225312

@AA : 세고 싶을 때 왜 당신의 것이 작동하지 않는지 추가했습니다.
Jochen Ritzel

알지만 내 경우에는 두 사전의 길이가 같습니다. 그리고 그것이 프로그램이 작동하는 방식이기 때문에 그들은 항상있을 것입니다.
user225312

5
Python 3.6부터 dict는 기본적으로 주문됩니다.
Phil

163
def dict_compare(d1, d2):
    d1_keys = set(d1.keys())
    d2_keys = set(d2.keys())
    shared_keys = d1_keys.intersection(d2_keys)
    added = d1_keys - d2_keys
    removed = d2_keys - d1_keys
    modified = {o : (d1[o], d2[o]) for o in shared_keys if d1[o] != d2[o]}
    same = set(o for o in shared_keys if d1[o] == d2[o])
    return added, removed, modified, same

x = dict(a=1, b=2)
y = dict(a=2, b=2)
added, removed, modified, same = dict_compare(x, y)

7
이것은 실제로 dict에서 변경 가능한 값을 처리합니다!
Tim Tisdall

1
이것을 실행할 때 여전히 변경 가능한 값을 처리하는 데 오류가 발생합니다. ValueError : DataFrame의 실제 값이 모호합니다. a.empty, a.bool (), a.item (), a.any () 또는 a.all ()을 사용하십시오.
Afflatus

2
@ Afflatus- DataFrames는 의도적으로 (길이가 1이 아닌 한) 진실한 비교를 허용하지 않습니다 numpy.ndarray. -credit to stackoverflow.com/a/33307396/994076
Daniel Myers

이것은 절대적인 보석입니다.
pfabri

125

dic1 == dic2

에서 파이썬 문서 :

설명하기 위해 다음의 예는 모두 사전 반환 동일을 하기 {"one": 1, "two": 2, "three": 3}:

>>> a = dict(one=1, two=2, three=3)
>>> b = {'one': 1, 'two': 2, 'three': 3}
>>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
>>> d = dict([('two', 2), ('one', 1), ('three', 3)])
>>> e = dict({'three': 3, 'one': 1, 'two': 2})
>>> a == b == c == d == e
True

첫 번째 예에서와 같이 키워드 인수를 제공하면 유효한 Python 식별자 인 키에 대해서만 작동합니다. 그렇지 않으면 유효한 키를 사용할 수 있습니다.

py2및 모두에 유효합니다 py3.


3
@ ErkinAlpGüney에 동의하지 않습니다. 증거를 제공해 주시겠습니까?
Qi Luo

4
@ ErkinAlpGüney에 동의하지 않습니다. 공식 문서에 따르면 ==는 사전을 주소가 아니라 값으로 비교합니다. docs.python.org/2/library/stdtypes.html#mapping-types-dict
Matthew Nakayama

3
Python 2.7.13에서 작동
Jesuisme

4
@ankostis :OrderedDict != dict
CONvid19

3
이것이 사실이 아닌 경우 입력을 제공해 주시겠습니까?
CONvid19

55

나는 파이썬을 처음 사용하지만 @mouad와 비슷한 것을했습니다.

unmatched_item = set(dict_1.items()) ^ set(dict_2.items())
len(unmatched_item) # should be 0

XOR 연산자 ( ^)는 dict의 두 요소가 동일 할 때 dict의 모든 요소를 ​​제거해야합니다.


28
불행히도 dict의 값을 변경할 수있는 경우 (예 : 해시 가능하지 않은 경우) 작동하지 않습니다. (예를 {'a':{'b':1}}제공 TypeError: unhashable type: 'dict')
팀 Tisdall

54

아무도 언급하지 않은 것 같으 deepdiff므로 여기에 추가하여 완전성을기할 것입니다. 나는 일반적으로 (중첩 된) 객체를 얻는 것이 매우 편리하다는 것을 알았습니다.

설치

pip install deepdiff

샘플 코드

import deepdiff
import json

dict_1 = {
    "a": 1,
    "nested": {
        "b": 1,
    }
}

dict_2 = {
    "a": 2,
    "nested": {
        "b": 2,
    }
}

diff = deepdiff.DeepDiff(dict_1, dict_2)
print(json.dumps(diff, indent=4))

산출

{
    "values_changed": {
        "root['a']": {
            "new_value": 2,
            "old_value": 1
        },
        "root['nested']['b']": {
            "new_value": 2,
            "old_value": 1
        }
    }
}

검사 결과를 예쁘게 인쇄하는 것에 대한 참고 사항 : 위의 코드는 두 dicts에 동일한 속성 키가있는 경우 (예 에서와는 다른 속성 값으로 가능) 작동합니다. 는 IF 그러나, "extra"속성의 존재는 하나의 dicts json.dumps()실패

TypeError: Object of type PrettyOrderedSet is not JSON serializable

해결책 : 사용 diff.to_json()하고 json.loads()/ / json.dumps()예쁘게 인쇄하십시오.

import deepdiff
import json

dict_1 = {
    "a": 1,
    "nested": {
        "b": 1,
    },
    "extra": 3
}

dict_2 = {
    "a": 2,
    "nested": {
        "b": 2,
    }
}

diff = deepdiff.DeepDiff(dict_1, dict_2)
print(json.dumps(json.loads(diff.to_json()), indent=4))  

산출:

{
    "dictionary_item_removed": [
        "root['extra']"
    ],
    "values_changed": {
        "root['a']": {
            "new_value": 2,
            "old_value": 1
        },
        "root['nested']['b']": {
            "new_value": 2,
            "old_value": 1
        }
    }
}

대안 : use를 사용 pprint하면 다른 형식이됩니다.

import pprint

# same code as above

pprint.pprint(diff, indent=4)

산출:

{   'dictionary_item_removed': [root['extra']],
    'values_changed': {   "root['a']": {   'new_value': 2,
                                           'old_value': 1},
                          "root['nested']['b']": {   'new_value': 2,
                                                     'old_value': 1}}}

2
흥미 롭군 답변 해 주셔서 감사합니다. 적어도 내가 유용합니다. 이 답변에는 더 많은 투표가 필요합니다.
Archit Kapoor

46

그냥 사용하십시오 :

assert cmp(dict1, dict2) == 0

6
이 작업은 두 내용이 동일한 지 확인하는 것뿐만 아니라 차이점에 대한 보고서를 제공하는 것 같습니다
Diego Tercero

29
나는 이것이 동일하다고 믿는다dict1 == dict2
Trey Hunner

10
Python3.5를 사용하는 모든 사용자의 경우, cmp제거 된 내장 (그리고로 처리해야 하기 전에 제거 가 제안 대안 :. (a > b) - (a < b) == cmp(a, b)기능적으로 동등한에 대한 (또는 더 나은 __eq____hash__)
nerdwaller

3
@nerdwaller-dicts는 주문 가능한 유형이 아니므로 dict_a> dict_b는 다음을 발생시킵니다 TypeError.unorderable types: dict() < dict()
Stefano

2
@ 스테파노 : 좋은 전화, 내 의견은 파이썬에서 일반적인 비교를 위해 더 많았습니다 (실제 답변, 실수에주의를 기울이지 않았습니다).
nerdwaller

9

@mouad의 대답은 두 사전에 간단한 값만 포함되어 있다고 가정하면 좋습니다. 그러나 사전이 포함 된 사전이있는 경우 사전을 해시 할 수 없으므로 예외가 발생합니다.

내 머리 꼭대기에서 다음과 같이 작동 할 수 있습니다.

def compare_dictionaries(dict1, dict2):
     if dict1 is None or dict2 is None:
        print('Nones')
        return False

     if (not isinstance(dict1, dict)) or (not isinstance(dict2, dict)):
        print('Not dict')
        return False

     shared_keys = set(dict1.keys()) & set(dict2.keys())

     if not ( len(shared_keys) == len(dict1.keys()) and len(shared_keys) == len(dict2.keys())):
        print('Not all keys are shared')
        return False


     dicts_are_equal = True
     for key in dict1.keys():
         if isinstance(dict1[key], dict) or isinstance(dict2[key], dict):
             dicts_are_equal = dicts_are_equal and compare_dictionaries(dict1[key], dict2[key])
         else:
             dicts_are_equal = dicts_are_equal and all(atleast_1d(dict1[key] == dict2[key]))

     return dicts_are_equal

not isinstance(dict1, dict)대신에 사용하면 (dict1 [key] == dict2 [key]) all (atleast_1d (dict1 [key] == dict2 [key]))`을 type(dict1) is not dict기반으로 다른 클래스에서 작동하여 배열을 적어도 처리합니다. dict. Also, instead of , you can do
EL_DON

+1이지만 거짓이 for loop되는 즉시 벗어날 수 dicts_are_equal있습니다. 더 이상 계속할 필요가 없습니다.
pfabri

6

OP의 마지막 메모까지 또 다른 가능성 은 JSON으로 덤프 된 dict 의 해시 ( SHA또는 MD) 를 비교하는 것 입니다. 해시 구성 방식은 동일하면 소스 문자열도 동일하게 보장합니다. 이것은 매우 빠르고 수학적으로 들립니다.

import json
import hashlib

def hash_dict(d):
    return hashlib.sha1(json.dumps(d, sort_keys=True)).hexdigest()

x = dict(a=1, b=2)
y = dict(a=2, b=2)
z = dict(a=1, b=2)

print(hash_dict(x) == hash_dict(y))
print(hash_dict(x) == hash_dict(z))

2
그것은 완전히 잘못되었습니다. 데이터를 json으로 구문 분석하는 것은 실제로 느립니다. 그러면 방금 만든 거대한 울음 소리를 해싱하는 것이 훨씬 더 나쁩니다. 당신은 그렇게해서는 안됩니다
Bruno

7
@Bruno : OP 인용 : "더 나은 속도는 아니고, 코드 우아함에 대해 이야기하고 있습니다"
WoJ

2
전혀 우아하지 않고 안전하지 않으며 매우 간단한 문제로 지나치게 복잡합니다
Bruno

7
@Bruno : 우아함은 주관적입니다. 나는 당신이 그것을 좋아하지 않는다는 것을 이해할 수 있습니다. 이것은 "잘못된"과 동일하지 않습니다.
WoJ

4
이것은 좋은 대답입니다. json.dumps(d, sort_keys=True)정식 JSON을 제공하므로 두 dict가 동일하다는 것을 확신 할 수 있습니다. 또한 그것은 당신이 달성하려는 것에 달려 있습니다. 값이 JSON serizalizable이 아닌 즉시 실패합니다. 따라서 비효율적이라고 말하는 사람은 ujson 프로젝트를 살펴보십시오.
Natim

6

이 기능은 깨끗하고 직관적 인 훌륭한 IMO입니다. 그러나 당신에게 (또 다른) 대답을하기 위해, 여기에 나의 길이 있습니다 :

def compare_dict(dict1, dict2):
    for x1 in dict1.keys():
        z = dict1.get(x1) == dict2.get(x1)
        if not z:
            print('key', x1)
            print('value A', dict1.get(x1), '\nvalue B', dict2.get(x1))
            print('-----\n')

당신이나 다른 사람에게 유용 할 수 있습니다 ..

편집하다:

위의 재귀 버전을 만들었습니다. 다른 답변에서는 보지 못했습니다.

def compare_dict(a, b):
    # Compared two dictionaries..
    # Posts things that are not equal..
    res_compare = []
    for k in set(list(a.keys()) + list(b.keys())):
        if isinstance(a[k], dict):
            z0 = compare_dict(a[k], b[k])
        else:
            z0 = a[k] == b[k]

        z0_bool = np.all(z0)
        res_compare.append(z0_bool)
        if not z0_bool:
            print(k, a[k], b[k])
    return np.all(res_compare)

2
두 가지 방식으로 작동하도록 개선합시다. 2 행 : "set (dict1.keys ()). union (dict2.keys ()) x1의 경우 :"
nkadwa

감사합니다 @nkadwa, 지금
zwep

5

키와 값에서 두 개의 dicts가 같은지 테스트하려면 다음을 수행하십시오.

def dicts_equal(d1,d2):
    """ return True if all keys and values are the same """
    return all(k in d2 and d1[k] == d2[k]
               for k in d1) \
        and all(k in d1 and d1[k] == d2[k]
               for k in d2)

다른 값을 반환하려면 다르게 작성하십시오.

def dict1_minus_d2(d1, d2):
    """ return the subset of d1 where the keys don't exist in d2 or
        the values in d2 are different, as a dict """
    return {k,v for k,v in d1.items() if k in d2 and v == d2[k]}

당신은 그것을 두 번 호출해야합니다

dict1_minus_d2(d1,d2).extend(dict1_minus_d2(d2,d1))

3

암호

def equal(a, b):
    type_a = type(a)
    type_b = type(b)
    
    if type_a != type_b:
        return False
    
    if isinstance(a, dict):
        if len(a) != len(b):
            return False
        for key in a:
            if key not in b:
                return False
            if not equal(a[key], b[key]):
                return False
        return True

    elif isinstance(a, list):
        if len(a) != len(b):
            return False
        while len(a):
            x = a.pop()
            index = indexof(x, b)
            if index == -1:
                return False
            del b[index]
        return True
        
    else:
        return a == b

def indexof(x, a):
    for i in range(len(a)):
        if equal(x, a[i]):
            return i
    return -1

테스트

>>> a = {
    'number': 1,
    'list': ['one', 'two']
}
>>> b = {
    'list': ['two', 'one'],
    'number': 1
}
>>> equal(a, b)
True

3

요즘 ==과의 간단한 비교로 충분합니다 (파이썬 3.8). 동일한 순서를 다른 순서로 비교할 때도 (마지막 예). 가장 좋은 방법은 타사 패키지가 필요하지 않다는 것입니다.

a = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}
b = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}

c = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}
d = {'one': 'dog', 'two': 'cat', 'three': 'mouse', 'four': 'fish'}

e = {'one': 'cat', 'two': 'dog', 'three': 'mouse'}
f = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}

g = {'two': 'cat', 'one': 'dog', 'three': 'mouse'}
h = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}


print(a == b) # True
print(c == d) # False
print(e == f) # False
print(g == h) # True

2

응답이 늦는 것이 결코 낫지 않습니다!

Not_Equal 비교는 Equal을 비교하는 것보다 효율적입니다. 따라서 한 dict의 키 값이 다른 dict에서 발견되지 않으면 두 dict는 동일하지 않습니다. 아래 코드는 기본 dict을 비교할 수 있으므로 getitem [] 대신 get을 사용한다는 것을 고려합니다 .

하나의 dict에 dicts에 None as 값이 있고 해당 키가 다른 dict에 존재하지 않는 경우를 위해 get call에서 기본값으로 임의의 값을 사용하여 검색되는 키와 동일합니다. 또한 키와 값을 동시에 양쪽에서 확인하기 때문에 get! = 조건이 효율성이 아닌 조건보다 먼저 점검됩니다.

def Dicts_Not_Equal(first,second):
    """ return True if both do not have same length or if any keys and values are not the same """
    if len(first) == len(second): 
        for k in first:
            if first.get(k) != second.get(k,k) or k not in second: return (True)
        for k in second:         
            if first.get(k,k) != second.get(k) or k not in first: return (True)
        return (False)   
    return (True)

2

Python 3에서 완벽하게 작동하는이 솔루션을 사용하고 있습니다.


import logging
log = logging.getLogger(__name__)

...

    def deep_compare(self,left, right, level=0):
        if type(left) != type(right):
            log.info("Exit 1 - Different types")
            return False

        elif type(left) is dict:
            # Dict comparison
            for key in left:
                if key not in right:
                    log.info("Exit 2 - missing {} in right".format(key))
                    return False
                else:
                    if not deep_compare(left[str(key)], right[str(key)], level +1 ):
                        log.info("Exit 3 - different children")
                        return False
            return True
        elif type(left) is list:
            # List comparison
            for key in left:
                if key not in right:
                    log.info("Exit 4 - missing {} in right".format(key))
                    return False
                else:
                    if not deep_compare(left[left.index(key)], right[right.index(key)], level +1 ):
                        log.info("Exit 5 - different children")
                        return False
            return True
        else:
            # Other comparison
            return left == right

        return False

dict, list 및 "=="연산자를 직접 구현하는 다른 유형을 비교합니다. 다른 것을 비교해야하는 경우 "if tree"에 새 분기를 추가해야합니다.

희망이 도움이됩니다.


2

python3의 경우 :

data_set_a = dict_a.items()
data_set_b = dict_b.items()

difference_set = data_set_a ^ data_set_b

1
>>> hash_1
{'a': 'foo', 'b': 'bar'}
>>> hash_2
{'a': 'foo', 'b': 'bar'}
>>> set_1 = set (hash_1.iteritems())
>>> set_1
set([('a', 'foo'), ('b', 'bar')])
>>> set_2 = set (hash_2.iteritems())
>>> set_2
set([('a', 'foo'), ('b', 'bar')])
>>> len (set_1.difference(set_2))
0
>>> if (len(set_1.difference(set_2)) | len(set_2.difference(set_1))) == False:
...    print "The two hashes match."
...
The two hashes match.
>>> hash_2['c'] = 'baz'
>>> hash_2
{'a': 'foo', 'c': 'baz', 'b': 'bar'}
>>> if (len(set_1.difference(set_2)) | len(set_2.difference(set_1))) == False:
...     print "The two hashes match."
...
>>>
>>> hash_2.pop('c')
'baz'

다른 옵션이 있습니다 :

>>> id(hash_1)
140640738806240
>>> id(hash_2)
140640738994848

보시다시피 두 ID가 다릅니다. 그러나 풍부한 비교 연산자 는 트릭을 수행하는 것처럼 보입니다.

>>> hash_1 == hash_2
True
>>>
>>> hash_2
{'a': 'foo', 'b': 'bar'}
>>> set_2 = set (hash_2.iteritems())
>>> if (len(set_1.difference(set_2)) | len(set_2.difference(set_1))) == False:
...     print "The two hashes match."
...
The two hashes match.
>>>

1

PyUnit에는 사전을 아름답게 비교하는 방법이 있습니다. 다음 두 사전을 사용하여 테스트했으며 원하는 것을 정확하게 수행합니다.

d1 = {1: "value1",
      2: [{"subKey1":"subValue1",
           "subKey2":"subValue2"}]}
d2 = {1: "value1",
      2: [{"subKey2":"subValue2",
           "subKey1": "subValue1"}]
      }


def assertDictEqual(self, d1, d2, msg=None):
        self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
        self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')

        if d1 != d2:
            standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
            diff = ('\n' + '\n'.join(difflib.ndiff(
                           pprint.pformat(d1).splitlines(),
                           pprint.pformat(d2).splitlines())))
            standardMsg = self._truncateMessage(standardMsg, diff)
            self.fail(self._formatMessage(msg, standardMsg))

unittest프로덕션 코드로 가져 오기 를 권장하지 않습니다 . 내 생각은 PyUnit의 소스가 프로덕션 환경에서 실행되도록 재구성 될 수 있다는 것입니다. 그것은 사용 pprint하는 "꽤 인쇄"사전을. 이 코드를 "제작 준비"가되도록 쉽게 적용 할 수 있습니다.


1

사전보기 객체를 참조하십시오 : https://docs.python.org/2/library/stdtypes.html#dict

이 방법으로 dictView1에서 dictView2를 빼면 dictView2와 다른 키 / 값 쌍 세트가 리턴됩니다.

original = {'one':1,'two':2,'ACTION':'ADD'}
originalView=original.viewitems()
updatedDict = {'one':1,'two':2,'ACTION':'REPLACE'}
updatedDictView=updatedDict.viewitems()
delta=original | updatedDict
print delta
>>set([('ACTION', 'REPLACE')])

이러한 사전 뷰 객체를 교차, 합집합, 차이 (위 그림 참조), 대칭 적 차이로 교차 할 수 있습니다.
보다 나은? 빨리? -확실하지는 않지만 표준 라이브러리의 일부-이식성을 크게 향상시킵니다.


1

아래 코드는 파이썬에서 dict 목록을 비교하는 데 도움이됩니다.

def compate_generic_types(object1, object2):
    if isinstance(object1, str) and isinstance(object2, str):
        return object1 == object2
    elif isinstance(object1, unicode) and isinstance(object2, unicode):
        return object1 == object2
    elif isinstance(object1, bool) and isinstance(object2, bool):
        return object1 == object2
    elif isinstance(object1, int) and isinstance(object2, int):
        return object1 == object2
    elif isinstance(object1, float) and isinstance(object2, float):
        return object1 == object2
    elif isinstance(object1, float) and isinstance(object2, int):
        return object1 == float(object2)
    elif isinstance(object1, int) and isinstance(object2, float):
        return float(object1) == object2

    return True

def deep_list_compare(object1, object2):
    retval = True
    count = len(object1)
    object1 = sorted(object1)
    object2 = sorted(object2)
    for x in range(count):
        if isinstance(object1[x], dict) and isinstance(object2[x], dict):
            retval = deep_dict_compare(object1[x], object2[x])
            if retval is False:
                print "Unable to match [{0}] element in list".format(x)
                return False
        elif isinstance(object1[x], list) and isinstance(object2[x], list):
            retval = deep_list_compare(object1[x], object2[x])
            if retval is False:
                print "Unable to match [{0}] element in list".format(x)
                return False
        else:
            retval = compate_generic_types(object1[x], object2[x])
            if retval is False:
                print "Unable to match [{0}] element in list".format(x)
                return False

    return retval

def deep_dict_compare(object1, object2):
    retval = True

    if len(object1) != len(object2):
        return False

    for k in object1.iterkeys():
        obj1 = object1[k]
        obj2 = object2[k]
        if isinstance(obj1, list) and isinstance(obj2, list):
            retval = deep_list_compare(obj1, obj2)
            if retval is False:
                print "Unable to match [{0}]".format(k)
                return False

        elif isinstance(obj1, dict) and isinstance(obj2, dict):
            retval = deep_dict_compare(obj1, obj2)
            if retval is False:
                print "Unable to match [{0}]".format(k)
                return False
        else:
            retval = compate_generic_types(obj1, obj2)
            if retval is False:
                print "Unable to match [{0}]".format(k)
                return False

    return retval

3
스택 오버플로에 오신 것을 환영합니다! 이 코드 스 니펫은 문제를 해결할 수 있지만 설명을 포함하면 게시물의 품질을 향상시키는 데 실제로 도움이됩니다. 앞으로 독자에게 질문에 대한 답변을 제공하고 있으며 해당 사람들이 코드 제안의 이유를 모를 수도 있습니다. 설명 주석으로 코드를 복잡하게 만들지 마십시오. 코드와 설명의 가독성이 떨어집니다!
Filnor

1
>>> x = {'a':1,'b':2,'c':3}
>>> x
{'a': 1, 'b': 2, 'c': 3}

>>> y = {'a':2,'b':4,'c':3}
>>> y
{'a': 2, 'b': 4, 'c': 3}

METHOD 1:

>>> common_item = x.items()&y.items() #using union,x.item() 
>>> common_item
{('c', 3)}

METHOD 2:

 >>> for i in x.items():
        if i in y.items():
           print('true')
        else:
           print('false')


false
false
true

0

Python 3.6에서는 다음과 같이 수행 할 수 있습니다.

if (len(dict_1)==len(dict_2): 
  for i in dict_1.items():
        ret=bool(i in dict_2.items())

dict_1의 모든 항목이 dict_2에 있으면 ret 변수는 true입니다.


0

내 대답은 다음과 같습니다.

def dict_equals(da, db):
    if not isinstance(da, dict) or not isinstance(db, dict):
        return False
    if len(da) != len(db):
        return False
    for da_key in da:
        if da_key not in db:
            return False
        if not isinstance(db[da_key], type(da[da_key])):
            return False
        if isinstance(da[da_key], dict):
            res = dict_equals(da[da_key], db[da_key])
            if res is False:
                return False
        elif da[da_key] != db[da_key]:
            return False
    return True

a = {1:{2:3, 'name': 'cc', "dd": {3:4, 21:"nm"}}}
b = {1:{2:3, 'name': 'cc', "dd": {3:4, 21:"nm"}}}
print dict_equals(a, b)

희망이 도움이됩니다!


0

한 사전을 반복하고 프로세스에서 다른 사전을 확인하는 것이 어떻습니까 (두 사전에 동일한 키가 있다고 가정)?

x = dict(a=1, b=2)
y = dict(a=2, b=2)

for key, val in x.items():
    if val == y[key]:
        print ('Ok', val, y[key])
    else:
        print ('Not', val, y[key])

산출:

Not 1 2
Ok 2 2

0

두 사전을 심도있게 비교할 수있는 가장 쉬운 방법 (및 그 중에서 가장 강력한 방법 중 하나)을 JSON 형식으로 직렬화하고 키를 정렬하고 문자열 결과를 비교하는 것입니다.

import json
if json.dumps(x, sort_keys=True) == json.dumps(y, sort_keys=True):
   ... Do something ...

-7
import json

if json.dumps(dict1) == json.dumps(dict2):
    print("Equal")

1
이것은 정확히 요청한 것을 수행하지 않을 수 있으며 json std lib를 가져 오지만 작동합니다 ( json.dumps기본 설정에 따라 결정적입니다).
Daniel Farrell
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.