2012-03-22 35 views
56

Jak obliczyć związek dwóch dict obiektów w Pythonie, gdzie (key, value) para występuje w rezultacie IFF key jest in albo DICT (chyba że istnieją duplikaty)?Unia obiektów Dict w Pythonie

Na przykład związek {'a' : 0, 'b' : 1} i {'c' : 2} to {'a' : 0, 'b' : 1, 'c' : 2}.

Najlepiej można to zrobić bez modyfikacji wejścia dict. Przykład tego, gdzie jest to przydatne: Get a dict of all variables currently in scope and their values

+2

W jakim sensie to pytanie różni się od tego, które zostało połączone w Twojej odpowiedzi? –

+1

@RikPoggi: Inne pytanie, pomimo tytułu, pyta o to, jaka jest składnia '** d2' *. Zdarza się, że udziela odpowiedzi na to pytanie. –

Odpowiedz

55

This question podaje idiom. Za pomocą jednego z dicts jak argumenty słowo kluczowe aby konstruktora dict():

dict(y, **x) 

Duplikaty są rozstrzygane na korzyść wartości x; na przykład

dict({'a' : 'y[a]'}, **{'a', 'x[a]'}) == {'a' : 'x[a]'} 
+6

"Prostota jest lepsza niż złożona." :) Powinieneś użyć funkcji 'update' funkcji' dict'. – shahjapan

+12

Jak to jest 'tmp = dict (y); tmp.update (x); do_something (tmp) 'prostsze? –

+6

@shahjapan To nie jest skomplikowane, jest to świetne wykorzystanie struktury dyktowanej przez Pythona. A to różni się od aktualizacji (to rozwiązanie niczego nie aktualizuje). – lajarre

53

Można również użyć update metodę dict jak

a = {'a' : 0, 'b' : 1} 
b = {'c' : 2} 

a.update(b) 
print a 
5

Jeśli potrzebujesz obu dicts pozostać niezależny, i mogą być aktualizowane, można utworzyć pojedynczy obiekt że zapytania zarówno słowniki w jego __getitem__ metoda (i implementuj get, __contains__ i inną metodę mapowania, jaka jest potrzebna).

Minimalistyczna Przykładem może być tak:

class UDict(object): 
    def __init__(self, d1, d2): 
     self.d1, self.d2 = d1, d2 
    def __getitem__(self, item): 
     if item in self.d1: 
      return self.d1[item] 
     return self.d2[item] 

I to działa:

>>> a = UDict({1:1}, {2:2}) 
>>> a[2] 
2 
>>> a[1] 
1 
>>> a[3] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 7, in __getitem__ 
KeyError: 3 
>>> 
18

dwa słowniki

def union2(dict1, dict2): 
    return dict(list(dict1.items()) + list(dict2.items())) 

n słowniki

def union(*dicts): 
    return dict(itertools.chain.from_iterable(dct.items() for dct in dicts)) 
+12

Lub znacznie bardziej przystępnie, 'dict (i dla dct w dyktach dla i in dct.items())' – Eric

+0

Dlaczego konwertowanie do listy()? 'def union2 (dict1, dict2):' 'return dict (dict1.items() + dict2.items())' – kinORnirvana

+1

@kinORnirvana W python 3: a = {'x': 1}; type (a.items()) =>