Search code examples
pythondictionarycounter

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?


Solution

  • 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.