字典中的差异

8

我正在尝试区分字典中的差异,以确定某个元素是被添加还是被删除,并且该元素具体是什么。

以下是一个值被添加的例子:

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

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

这里是一个删除值的示例:

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

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

问题是我不知道如何接收差异。有人知道如何达到这样的结果吗?

额外信息(不确定是否需要):

  • 这也适用于原始值和新值的0和1。
  • 1和2不能同时处于活动状态。如果一个有值,另一个就为False。

1
为什么不在dict周围创建一个“包装器”,并使用它来跟踪添加/删除的内容?(我不知道在Python中这有多难,但在C#中相当简单)。 - Michael Todd
你的问题未明确。如果我在你的第一个例子中删除16 添加2,会发生什么?差异必须同时为True和False。 - phooji
假设那永远不会发生,phooji。 :) - dbdii407
6个回答

6

如我在另一个问题中所解释的,有一个专门用于此任务的PyPI库,即datadiff库。它易于使用,您可以使用输出来完成必要的操作。


3
我认为这篇文章写得很通俗易懂:
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'}}

2
这里有一个可以生成两个字典差异的函数链接,附带额外的注释/代码示例: http://code.activestate.com/recipes/576644-diff-two-dictionaries/ 以下是代码:
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

1

你可以在Python中将dic[2]暂时转换为set,然后使用-来获取差异。


0

这个怎么样:

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

-1

这可以在一行代码中完成。

[b[k] for k in a.keys() if not k in b]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接