Reputation: 322
I have two dictionaries, let's say:
dict_a = {"A": 3.0, "C": 4.0, "B": 6.0}
dict_b = {"A": 3.0, "C": 5.0, "D": 1.0}
and I want to calculate a subtraction dict_a - dict_b
so the output gives me:
{"A": 0.0, "B": 6.0, "C": -1.0, "D": -1.0}
Googling for some time I have seen people using Counter to perform operations like this, but doing something simple like
dict(Counter(dict_a) - Counter(dict_b))
only gives me
{"A": 0.0, "B": 6.0}
i.e., if the key is not in dict_a
, it won't appear in the output.
So far, I have managed the following solution:
dict_b2 = dict_b.copy()
dict_c = {}
for i in dict_a.keys():
dict_c.update({i: dict_a[i] - dict_b2.pop(i,0.0)})
# Changes sign to the remaining values from dict_b2
dict_c.update({k: 0.0 - v for k, v in dict_b2.iteritems()})
but I know there has to be a much more elegant and efficient way of doing it.
Any ideas?
Upvotes: 2
Views: 1813
Reputation: 34146
You can try using a dict comprehension:
new_dict = {k:dict_a.get(k, 0) - dict_b.get(k, 0)
for k in set(dict_a).union(set(dict_b))}
# {'A': 0.0, 'C': -1.0, 'B': 6.0, 'D': -1.0}
Here we are using dict#get(key, default)
to avoid getting a KeyError
(when the key doesn't belong to one of the dictionaries).
Upvotes: 3
Reputation: 309929
It turns out that Counter
has a (not very well documented) subtract
method:
>>> dict_a = {"A": 3.0, "C": 4.0, "B": 6.0}
>>> dict_b = {"A": 3.0, "C": 5.0, "D": 1.0}
>>> from collections import Counter
>>> a = Counter(dict_a)
>>> a.subtract(dict_b)
>>> a
Counter({'B': 6.0, 'A': 0.0, 'C': -1.0, 'D': -1.0})
Note that this doesn't suffer from the "no values below 0" constraint which is imposed on Counter.__sub__
, but it does do the operation in-place.
One thing that is a little cool is that I didn't have to convert both dicts to a Counter -- only the one on the left side of the operation.
Upvotes: 7