How to get the difference between two dictionaries in Python?

前端 未结 9 1301
庸人自扰
庸人自扰 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 04:58

    Old question, but thought I'd share my solution anyway. Pretty simple.

    dicta_set = set(dicta.items()) # creates a set of tuples (k/v pairs)
    dictb_set = set(dictb.items())
    setdiff = dictb_set.difference(dicta_set) # any set method you want for comparisons
    for k, v in setdiff: # unpack the tuples for processing
        print(f"k/v differences = {k}: {v}")
    

    This code creates two sets of tuples representing the k/v pairs. It then uses a set method of your choosing to compare the tuples. Lastly, it unpacks the tuples (k/v pairs) for processing.

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

    Try the following snippet, using a dictionary comprehension:

    value = { k : second_dict[k] for k in set(second_dict) - set(first_dict) }
    

    In the above code we find the difference of the keys and then rebuild a dict taking the corresponding values.

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

    I think it's better to use the symmetric difference operation of sets to do that Here is the link to the doc.

    >>> dict1 = {1:'donkey', 2:'chicken', 3:'dog'}
    >>> dict2 = {1:'donkey', 2:'chimpansee', 4:'chicken'}
    >>> set1 = set(dict1.items())
    >>> set2 = set(dict2.items())
    >>> set1 ^ set2
    {(2, 'chimpansee'), (4, 'chicken'), (2, 'chicken'), (3, 'dog')}
    

    It is symmetric because:

    >>> set2 ^ set1
    {(2, 'chimpansee'), (4, 'chicken'), (2, 'chicken'), (3, 'dog')}
    

    This is not the case when using the difference operator.

    >>> set1 - set2
    {(2, 'chicken'), (3, 'dog')}
    >>> set2 - set1
    {(2, 'chimpansee'), (4, 'chicken')}
    

    However it may not be a good idea to convert the resulting set to a dictionary because you may lose information:

    >>> dict(set1 ^ set2)
    {2: 'chicken', 3: 'dog', 4: 'chicken'}
    
    0 讨论(0)
  • 2020-11-27 05:10
    def flatten_it(d):
        if isinstance(d, list) or isinstance(d, tuple):
            return tuple([flatten_it(item) for item in d])
        elif isinstance(d, dict):
            return tuple([(flatten_it(k), flatten_it(v)) for k, v in sorted(d.items())])
        else:
            return d
    
    dict1 = {'a': 1, 'b': 2, 'c': 3}
    dict2 = {'a': 1, 'b': 1}
    
    print set(flatten_it(dict1)) - set(flatten_it(dict2)) # set([('b', 2), ('c', 3)])
    # or 
    print set(flatten_it(dict2)) - set(flatten_it(dict1)) # set([('b', 1)])
    
    0 讨论(0)
  • 2020-11-27 05:12

    Another solution would be dictdiffer (https://github.com/inveniosoftware/dictdiffer).

    import dictdiffer                                          
    
    a_dict = {                                                 
      'a': 'foo',
      'b': 'bar',
      'd': 'barfoo'
    }                                                          
    
    b_dict = {                                                 
      'a': 'foo',                                              
      'b': 'BAR',
      'c': 'foobar'
    }                                                          
    
    for diff in list(dictdiffer.diff(a_dict, b_dict)):         
        print diff
    

    A diff is a tuple with the type of change, the changed value, and the path to the entry.

    ('change', 'b', ('bar', 'BAR'))
    ('add', '', [('c', 'foobar')])
    ('remove', '', [('d', 'barfoo')])
    
    0 讨论(0)
  • 2020-11-27 05:20

    This function gives you all the diffs (and what stayed the same) based on the dictionary keys only. It also highlights some nice Dict comprehension, Set operations and python 3.6 type annotations :)

    from typing import Dict, Any, Tuple
    def get_dict_diffs(a: Dict[str, Any], b: Dict[str, Any]) -> Tuple[Dict[str, Any], Dict[str, Any], Dict[str, Any], Dict[str, Any]]:
    
        added_to_b_dict: Dict[str, Any] = {k: b[k] for k in set(b) - set(a)}
        removed_from_a_dict: Dict[str, Any] = {k: a[k] for k in set(a) - set(b)}
        common_dict_a: Dict[str, Any] = {k: a[k] for k in set(a) & set(b)}
        common_dict_b: Dict[str, Any] = {k: b[k] for k in set(a) & set(b)}
        return added_to_b_dict, removed_from_a_dict, common_dict_a, common_dict_b
    

    If you want to compare the dictionary values:

    values_in_b_not_a_dict = {k : b[k] for k, _ in set(b.items()) - set(a.items())}
    
    0 讨论(0)
提交回复
热议问题