How to get the difference between two dictionaries in Python?

前端 未结 9 1302
庸人自扰
庸人自扰 2020-11-27 04:45

I have two dictionaries. I need to find the difference between the two which should give me both key and value.

I have searched and found some addons/packages like d

相关标签:
9条回答
  • 2020-11-27 05:20

    What about this? Not as pretty but explicit.

    orig_dict = {'a' : 1, 'b' : 2}
    new_dict = {'a' : 2, 'v' : 'hello', 'b' : 2}
    
    updates = {}
    for k2, v2 in new_dict.items():
        if k2 in orig_dict:    
            if v2 != orig_dict[k2]:
                updates.update({k2 : v2})
        else:
            updates.update({k2 : v2})
    
    #test it
    #value of 'a' was changed
    #'v' is a completely new entry
    assert all(k in updates for k in ['a', 'v'])
    
    0 讨论(0)
  • 2020-11-27 05:23

    A function using the symmetric difference set operator, as mentioned in other answers, which preserves the origins of the values:

    def diff_dicts(a, b, missing=KeyError):
        """
        Find keys and values which differ from `a` to `b` as a dict.
    
        If a value differs from `a` to `b` then the value in the returned dict will
        be: `(a_value, b_value)`. If either is missing then the token from 
        `missing` will be used instead.
    
        :param a: The from dict
        :param b: The to dict
        :param missing: A token used to indicate the dict did not include this key
        :return: A dict of keys to tuples with the matching value from a and b
        """
        return {
            key: (a.get(key, missing), b.get(key, missing))
            for key in dict(
                set(a.items()) ^ set(b.items())
            ).keys()
        }
    

    Example

    print(diff_dicts({'a': 1, 'b': 1}, {'b': 2, 'c': 2}))
    
    # {'c': (<class 'KeyError'>, 2), 'a': (1, <class 'KeyError'>), 'b': (1, 2)}
    

    How this works

    We use the symmetric difference set operator on the tuples generated from taking items. This generates a set of distinct (key, value) tuples from the two dicts.

    We then make a new dict from that to collapse the keys together and iterate over these. These are the only keys that have changed from one dict to the next.

    We then compose a new dict using these keys with a tuple of the values from each dict substituting in our missing token when the key isn't present.

    0 讨论(0)
  • 2020-11-27 05:25

    You were right to look at using a set, we just need to dig in a little deeper to get your method to work.

    First, the example code:

    test_1 = {"foo": "bar", "FOO": "BAR"}
    test_2 = {"foo": "bar", "f00": "b@r"}
    

    We can see right now that both dictionaries contain a similar key/value pair:

    {"foo": "bar", ...}
    

    Each dictionary also contains a completely different key value pair. But how do we detect the difference? Dictionaries don't support that. Instead, you'll want to use a set.

    Here is how to turn each dictionary into a set we can use:

    set_1 = set(test_1.items())
    set_2 = set(test_2.items())
    

    This returns a set containing a series of tuples. Each tuple represents one key/value pair from your dictionary.

    Now, to find the difference between set_1 and set_2:

    print set_1 - set_2
    >>> {('FOO', 'BAR')}
    

    Want a dictionary back? Easy, just:

    dict(set_1 - set_2)
    >>> {'FOO': 'BAR'}
    
    0 讨论(0)
提交回复
热议问题