2015-09-28 49 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())}