2013-07-16 14 views
13

mam dwa słowniki w Pythonie:Jak odjąć od wartości słowników

d1 = {'a': 10, 'b': 9, 'c': 8, 'd': 7} 
d2 = {'a': 1, 'b': 2, 'c': 3, 'e': 2} 

Chcę odjąć wartości pomiędzy słowniki D1-D2 i uzyskać wynik:

d3 = {'a': 9, 'b': 7, 'c': 5, 'd': 7 } 

Teraz używam dwie pętle, ale to rozwiązanie nie jest zbyt szybkie.

for x,i in enumerate(d2.keys()): 
     for y,j in enumerate(d1.keys()): 
+0

możliwe duplikat [Czy istnieje pythonic sposób połączyć dwa dicts (dodawanie wartości do kluczy, które pojawiają się w obu)?] (Http: // stackoverflow.com/questions/11011756/is-there-any-pythonic-way-to-combine-two-dicts-adding-values-for-keys-that-appe) –

Odpowiedz

18

myślę bardzo pythonowy sposób będzie za pomocą dict comprehension:

d3 = {key: d1[key] - d2.get(key, 0) for key in d1.keys()} 

Należy zauważyć, że działa to tylko w języku Python 2.7+ lub 3.

+2

To jest najszybsze rozwiązanie. Testowano wydajność za pomocą dwóch słowników z 1 milionami elementów. – Colargol

15

Użyj collections.Counter. Składnia jest bardzo proste:

>>> from collections import Counter 
>>> d1 = Counter({'a': 10, 'b': 9, 'c': 8, 'd': 7}) 
>>> d2 = Counter({'a': 1, 'b': 2, 'c': 3, 'e': 2}) 
>>> d3 = d1 - d2 
>>> print d3 
Counter({'a': 9, 'b': 7, 'd': 7, 'c': 5}) 
+0

... Nie wiedziałem, że możesz zrobić to z Counterem OO –

+2

@ JoelCornett Jakieś mocne rzeczy prawda? : p – TerryA

+3

@ Haidro Nie będzie działać z liczbami ujemnymi. –

3

Haidro pisał proste rozwiązanie, ale nawet bez collections trzeba tylko jedną pętlę:

d1 = {'a': 10, 'b': 9, 'c': 8, 'd': 7} 
d2 = {'a': 1, 'b': 2, 'c': 3, 'e': 2} 
d3 = {} 

for k, v in d1.items(): 
    d3[k] = v - d2.get(k, 0) # returns value if k exists in d2, otherwise 0 

print(d3) # {'c': 5, 'b': 7, 'a': 9, 'd': 7} 
8

Tylko aktualizacja odpowiedzi Haidro.

Zalecane stosowanie metody odejmowania zamiast "-".

d1.subtract (d2)

Kiedy - służy tylko pozytywne liczniki są aktualizowane do słownika. Zobacz przykłady poniżej

c = Counter(a=4, b=2, c=0, d=-2) 
d = Counter(a=1, b=2, c=3, d=4) 
a = c-d 
print(a)  # --> Counter({'a': 3}) 
c.subtract(d) 
print(c)  # --> Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6}) 

Uwaga Słownik jest aktualizowany, gdy stosowana jest metoda odejmowania.

I wreszcie używać dict (C), aby uzyskać Dictionary z Counter obiektu

+0

Czy masz coś przeciwko, jeśli dodam to do mojej odpowiedzi? Odwołuję się do ciebie :) – TerryA

+0

@Haidro Wcale nie. Zaktualizuj swoją odpowiedź – Hemanth

+0

Faktycznie, podczas testowania tego, nie zwraca on poszukiwanego słownika PO. Zwraca 'e = -2', gdzie OP po prostu chce usunąć' e'. – TerryA

Powiązane problemy