eSedano
eSedano

Reputation: 322

Subtracting elements from dictionaries

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

Answers (2)

Christian Tapia
Christian Tapia

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

mgilson
mgilson

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

Related Questions