如何根据权重合并字典?
d1 = {'weight':1, 'data': { 'apples': 8, 'oranges': 7 } }
d2 = {'weight':3, 'data': { 'apples': 4, 'bananas': 3 } }
all_dictionaries = [d1, d2, ... ]
def mergeDictionariesWithWeight(all_dictionaries)
我该如何把这些字典合并在一起(如果有重叠,就用权重来计算多个值)
这个函数会返回:
{ 'apples': 4, 'oranges': 7, 'bananas': 3 }
苹果的值是 4
,因为 8 * .25 + 4 * .75
补充:我刚写了一个计算平均值的函数,类似这样。但当然这和我想做的真的很不一样,因为我把所有东西放在一个列表里,然后只是除以长度。
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
5 个回答
1
from collections import defaultdict
def merge_dictionaries_with_weight(all_dictionaries):
totals = defaultdict(int)
result = defaultdict(int)
for each in all_dictionaries:
weight = float(each['weight'])
for key, value in each['data'].items():
totals[key] += weight
result[key] += weight * value
for key, total in totals.items():
result[key] /= total
return result
当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言进行解释。
1
这里有一个解决方案,它首先使用一个临时的字典把项目收集到一个列表中,然后再计算出最终的加权字典。其实可以不使用临时字典,但这样做更容易理解。
from collections import defaultdict
def mergeDictionariesWithWeight(dlist):
tmp = defaultdict(list)
for d in dlist:
weight = d['weight']
for k, v in d['data'].items():
tmp[k].append((weight, v))
r = {}
for k, v in tmp.items():
# If there's just one item, ignore the weight
if len(v) == 1:
r[k] = v[0][1]
else:
total_weight = sum((x[0] for x in v), 0.0)
r[k] = sum(x[1] * x[0]/total_weight for x in v)
return r
返回的结果是:{'apples': 5.0, 'oranges': 7, 'bananas': 3}(因为 8 * 0.25 + 4 * 0.75 = 5.0)
7
>>> from collections import defaultdict
>>> d=defaultdict(lambda:(0,0))
>>> for D in all_dictionaries:
... weight = D['weight']
... for k,v in D['data'].items():
... d[k]=d[k][0]+weight*v,d[k][1]+weight
...
>>> dict((k,v[0]/v[1]) for k,v in d.items())
{'apples': 5, 'oranges': 7, 'bananas': 3}
如果你需要浮点数结果
>>> dict((k,1.*v[0]/v[1]) for k,v in d.items())
{'apples': 5.0, 'oranges': 7.0, 'bananas': 3.0}
关于 defaultdict 的说明
你经常会看到 defaultdict(int)
或 defaultdict(list)
,甚至可能还有 defaultdict(set)
。传给 defaultdict 的参数必须是一个不带参数的可调用对象。调用这个参数的结果会在找不到某个键时使用。也就是说,调用这个参数会返回字典的 默认值。
举个例子
>>> d=defaultdict(int)
>>> d[1]
0
>>> d['foo']
0
这通常用来计数,因为 int()
会返回 0。如果你想让默认值变成 1 而不是 0,那就有点麻烦,因为你不能给 int 传参数,但你只需要一个返回 1 的可调用对象。使用 lambda 函数就可以轻松做到这一点。
>>> d=defaultdict(lambda:1)
>>> d[1]
1
>>> d['foo']
1
在这个回答中,我想记录加权总和和权重的总和。我可以通过使用一个 2 元组作为默认值来实现。
>>> d=defaultdict(lambda:(0,0))
>>> d[1]
(0, 0)
>>> d['foo']
(0, 0)