2015-09-28 19 views
10

Mam dwa słowniki. Muszę znaleźć różnicę między tymi dwoma, które powinny dać mi klucz i wartość.Jak odróżnić dwa słowniki w języku Python?

Szukałem i znalazłem kilka dodatków/pakietów, takich jak datadiff, dictdiff-master, ale kiedy próbuję go w Pythonie 2.7, nie ma zdefiniowanego takiego modułu.

Użyłem zestawu tutaj.

first_dict = {} 
second_dict = {} 

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

wyjście >>> set ([ 'SCD-3547', 'SCD-3456'])

Dostaję tylko klucz, muszę nawet uzyskać wartości.

+0

Czy też trzeba znaleźć różnicy, czy klucze są identyczne, ale ich wartości są różne? –

+0

Proszę nie oznaczać swoich pytań jako "pilnych" tutaj - wszystkie pytania są równie ważne. Dzięki! – halfer

Odpowiedz

19

Wypróbuj poniższy fragment, używając słownika zrozumieniem:

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

W powyższym kodzie możemy zobaczyć różnicę kluczy a następnie odbudować dict podejmowanie odpowiednich wartości.

+1

dziękuję u Oscar :) –

+2

Ponieważ zarówno 'dict' jak i' set' są hashmapami, nie wiem, dlaczego 'dict' nie może obsłużyć metody' difference() ', biorąc pod uwagę, że' set' działa. – Ray

+1

To tylko daje ci dykt dla kluczy, które były w drugim dyktacie, ale nie w pierwszym. A co z rzeczami, które były w pierwszym, ale nie w drugim? – henryJack

5

Mieliście rację, patrząc na użycie zestawu, musimy po prostu zagłębić się nieco głębiej, aby metoda zadziałała.

pierwsze, przykładowy kod:

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

Widzimy teraz, że oba słowniki zawierają podobną parę klucz/wartość:

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

Każdy słownik zawiera również zupełnie inną parę wartości klucza . Ale jak możemy wykryć różnicę? Słowniki tego nie obsługują. Zamiast tego będziesz chciał użyć zestawu.

Oto jak włączyć każdy słownika do zestawu możemy użyć:

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

ta zwraca zestaw zawierający szereg krotek. Każda krotka reprezentuje jedną parę klucz/wartość ze słownika.

Teraz, aby zobaczyć różnicę między SET_1 i SET_2:

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

chcą słownika powrotem? Proste, wystarczy:

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

myślę, że lepiej jest użyć symetrycznego operację różnicy zbiorów zrobić, że (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')} 

Jest symetryczny, ponieważ:

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

To nie jest przypadek, gdy za pomocą operatora różnicy

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

Jednak to nie może być dobry pomysł, aby przekształcić otrzymaną wartość słownik, ponieważ możesz stracić informacje:

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

Doskonale, jest to mniej więcej to samo rozwiązanie zaproponowane przez Raymonda Hettingera prawie 9 lat temu na innym forum: http: //code.activestate.com/recipes/576644-diff-two-dictionaries/#c1 – cscanlin

1

Innym rozwiązaniem będzie 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 

Różnica jest krotką z typem zmiany, zmienioną wartością i ścieżką do wpisu.

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

Ta funkcja udostępnia wszystkie różnice (i to, co pozostało bez zmian) na podstawie tylko klawiszy słownika. Podkreśla też jakieś fajne DICT zrozumieniem, ustaw operacje i Python 3.6 adnotacji typu :)

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 

Jeśli chcesz porównać słownika wartości:

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