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

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

>>> 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쌍이 같은지 확인해야한다는 것을 잊어 버렸습니다 .



답변

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

아마도 이런 식으로 뭔가 :

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


답변

당신이하고 싶은 것은 단순히 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))]

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


답변

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)


답변

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.


답변

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

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

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


답변

아무도 언급하지 않은 것 같으 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}}}


답변

그냥 사용하십시오 :

assert cmp(dict1, dict2) == 0