2015-09-28 48 views
10

我有两本字典。我需要找到两者之间的区别,这应该给我两个关键和价值。如何区分Python中两个词典的区别?

我已经搜索并发现了一些像datadiff,dictdiff-master这样的插件/包,但是当我在Python 2.7中尝试它时,它说没有定义这样的模块。

我用这里设置。

first_dict = {} 
second_dict = {} 

value = set(second_dict)-set(first_dict) 
print value 

输出>>>集([ 'SCD-3547', 'SCD-3456'])

我得到唯一的关键,我需要连得值。

+0

你还需要找到,如果差键是相同的,但它们的值不同? –

+0

请不要在这里将您的问题标记为“紧急” - 所有问题都具有同等重要性。谢谢! – halfer

回答

19

试试下面的代码片段,使用字典理解:

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

在我们找到钥匙的差异上面的代码,然后重建dict采取相应的值。

+1

谢谢你奥斯卡:) –

+2

由于'dict'和'set'都是hashmaps,我不知道'dict'不能支持'difference()'方法,因为'set'。 – Ray

+1

这只是给你在第二个字典,但不是在第一个键的字典。那些在第一个但不是第二个的东西呢? – henryJack

5

你是正确的看待使用一套,我们只需要深入挖掘一点,让你的方法工作。

首先,示例代码:

test_1 = {"foo": "bar", "FOO": "BAR"} 
test_2 = {"foo": "bar", "f00": "[email protected]"} 

我们可以看到,现在这两个字典包含类似的键/值对:

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

每个字典还包含一个完全不同的键值对。但是,我们如何检测差异?字典不支持。相反,你会想要使用一套。

这里是如何把每个字典成一组,我们可以使用:

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

这将返回一个包含一系列的元组的一组。每个元组代表您的字典中的一个键/值对。

现在,找到SET_1和终端SET_2之间的区别:

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

想要一本字典背?很简单,只需:

dict(set_1 - set_2) 
>>> {'FOO': 'BAR'} 
9

我认为这是最好使用的集对称差操作要做到这一点(https://docs.python.org/2/library/sets.html)。

>>> 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')} 

它是对称的,因为:

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

使用差分算

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

时,但是它可能不为结果设置为转换一个好主意,这是不是这样的字典,因为你可能会丢失信息:

>>> dict(set1^set2) 
{2: 'chicken', 3: 'dog', 4: 'chicken'} 
+0

优秀,这是或多或少雷蒙德Hettinger建议近9年前在另一个论坛上:http: //code.activestate.com/recipes/576644-diff-two-dictionaries/#c1 – cscanlin

1

另一种解决方案是dictdifferhttps://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 

diff是一个元组,包含更改类型,更改后的值和条目路径。

('change', 'b', ('bar', 'BAR')) 
('add', '', [('c', 'foobar')]) 
('remove', '', [('d', 'barfoo')]) 
0

该函数仅基于字典键为您提供所有差异(以及保持不变)。报告还强调了一些不错的快译通理解,Set操作和Python 3.6类型注释:)

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 

如果要比较的字典

values_in_b_not_a_dict = {k : b[k] for k, _ in set(b.items()) - set(a.items())}