d1 = {'weight':1, 'data': { 'apples': 8, 'oranges': 7 } }
d2 = {'weight':3, 'data': { 'apples': 4, 'bananas': 3 } }
all_dictionaries = [d1, d2, ... ]
def mergeDictionariesWithWeight(all_dictionaries)
How do I merge these dictionaries together (if overlap, multiple value with the weight)
The function would return:
{ 'apples': 4, 'oranges': 7, 'bananas': 3 }
Apples is 4 because 8 * .25 + 4 * .75
Edit: I just wrote one that takes the average, something like this. But of course it’s really different from what I want to do, because I stick everything in a list and just divide by the length.
result = {}
keymap = {}
for the_dict in dlist:
for (k, v) in the_dict.items():
if not keymap.has_key(k):
keymap[k] = []
keymap[k].append(v)
for (k, v) in keymap.items():
average = sum(int(x) for x in keymap[k]) / float(len(keymap[k]))
result[k] = float(average)
return result
If you need floating point result
Notes about defaultdict
Often you see
defaultdict(int)ordefaultdict(list)maybe evendefaultdict(set). The argument to defaultdict must be callable with no parameters. The result of calling this parameter is used whenever a key is found to be missing. ie – calling this returns the default value for the dictionaryfor example
This is often used for counting things up because
int()returns 0. If you want the default value to be 1 instead of 0, it’s more tricky because you can’t pass a parameter to int, but all you need is a callable that returns 1. This can be accomplished without too much fuss by using a lambda function.In this answer, I want to keep track of the weighted total, and the total of the weights. I can do this by using a 2-tuple as the default value.