Difference in a dict

2020-07-06 06:35发布

I'm trying to figure out the difference in a dict, whether something was added or removed and from what.

Here is a case where a value is added:

original = {0: None, 1: False, 2: [16]}
new = {0: None, 1: False, 2: [2, 16]}

difference = True, {2: 2} # True = Added

And here is a case where a value is removed:

original = {0: None, 1: False, 2: [16, 64]}
new = {0: None, 1: False, 2: [64]}

difference = False, {2: 16} # False = Removed

The problem is that I have no idea how to recieve the difference. Would anyone happen to know how to achieve such a result?

Extra information (no idea if you'll need this):

  • This can apply to 0 and 1 of original and new as well.
  • 1 and 2 cannot be active at the same time. If one has values, the other is False.

6条回答
闹够了就滚
2楼-- · 2020-07-06 07:10

That can be done in one line.

[b[k] for k in a.keys() if not k in b]
查看更多
劳资没心,怎么记你
3楼-- · 2020-07-06 07:11

Here is a link to a function that can produce a "diff" of two dictionaries, followed by additional comments/code samples:

http://code.activestate.com/recipes/576644-diff-two-dictionaries/

Including code below:

KEYNOTFOUND = '<KEYNOTFOUND>'       # KeyNotFound for dictDiff

def dict_diff(first, second):
    """ Return a dict of keys that differ with another config object.  If a value is
        not found in one fo the configs, it will be represented by KEYNOTFOUND.
        @param first:   Fist dictionary to diff.
        @param second:  Second dicationary to diff.
        @return diff:   Dict of Key => (first.val, second.val)
    """
    diff = {}
    # Check all keys in first dict
    for key in first.keys():
        if (not second.has_key(key)):
            diff[key] = (first[key], KEYNOTFOUND)
        elif (first[key] != second[key]):
            diff[key] = (first[key], second[key])
    # Check all keys in second dict to find missing
    for key in second.keys():
        if (not first.has_key(key)):
            diff[key] = (KEYNOTFOUND, second[key])
    return diff
查看更多
小情绪 Triste *
4楼-- · 2020-07-06 07:13

What about something like:

def diff(a,b):
     ret_dict = {}
     for key,val in a.items():
         if b.has_key(key):
             if b[key] != val:
                 ret_dict[key] = [val,b[key]]
         else:
             ret_dict[key] = [val]
     for key,val in b.items():
         ret_dict.setdefault(key,[val])
     return ret_dict
查看更多
时光不老,我们不散
5楼-- · 2020-07-06 07:21

you may temporarily transfer dic[2] to a set in python, and use - to get the difference

查看更多
forever°为你锁心
6楼-- · 2020-07-06 07:26

As I've explained in an other question there is a library on PyPI just for this task, which is datadiff library. It's easy to use and you can use the output to do what you have to do.

查看更多
神经病院院长
7楼-- · 2020-07-06 07:29

I find this quite readable:

def dict_diff(left, right):
    diff = dict()
    diff['left_only'] = set(left) - set(right)
    diff['right_only'] = set(right) - set(left)
    diff['different'] = {k for k in set(left) & set(right) if left[k]!=right[k]}
    return diff

>>> d1 = dict(a=1, b=20, c=30, e=50)
>>> d2 = dict(a=1, b=200, d=400, e=500)
>>> dict_diff(d1, d2)
{'different': {'b', 'e'}, 'left_only': {'c'}, 'right_only': {'d'}}
查看更多
登录 后发表回答