ehacinom
ehacinom

Reputation: 8894

"Adding" dictionaries in python if some (key, value) pairs match

Three dictionaries:

d0 = {"a": "hello", "b": "world", "c": 11}
d1 = {"a": "hello", "b": "world", "c": 100}
d2 = {"a": "goodbye", "b": "world", "c": 10}

They should be placed in a list of dictionaries that I iteratively add to.

dictionaries = [d0]

How do you merge dictionaries and add the integer "c" values together iff "a" and "b" are the same (str) values?

Hopeful result:

d3 = {"a": "hello", "b": "world", "c": 111}
d2 = {"a": "goodbye", "b": "world", "c": 10}
dictionaries = [d2, d3] # any order

Upvotes: 0

Views: 68

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1124090

Collect your c values into a dictionary keyed by the a, b keys; using a collections.defaultdict() object makes this a little easier:

from collections import defaultdict

keyed = defaultdict(int)

for d in (d0, d1, d2):
    keyed[(d['a'], d['b'])] += d['c']

dictionaries = [{'a': a, 'b': b, 'c': c} for (a, b), c in keyed.items()]

The keyed defaultdict object defaults to 0 if a specific key is not yet part of the dictionary (calling int produces 0). The above loop then sums all values for 'c' for a given combination of the 'a' and 'b' values.

Demo:

>>> from collections import defaultdict
>>> d0 = {"a": "hello", "b": "world", "c": 11}
>>> d1 = {"a": "hello", "b": "world", "c": 100}
>>> d2 = {"a": "goodbye", "b": "world", "c": 10}
>>> keyed = defaultdict(int)
>>> for d in (d0, d1, d2):
...     keyed[(d['a'], d['b'])] += d['c']
... 
>>> keyed
defaultdict(<type 'int'>, {('hello', 'world'): 111, ('goodbye', 'world'): 10})
>>> [{'a': a, 'b': b, 'c': c} for (a, b), c in keyed.items()]
[{'a': 'hello', 'c': 111, 'b': 'world'}, {'a': 'goodbye', 'c': 10, 'b': 'world'}]

Upvotes: 2

Related Questions