如何在没有明确定义权重的情况下使用字典值来计算加权值的总和?

时间:2016-01-07 06:21:49

标签: python list dictionary weighted-average

作为一个例子,我有一个字典如下:

mydict = {A:['asdasd',2,3], B:['asdasd',4,5], C:['rgerg',9,10]}

如何只获得一个数字,该数字基本上是dict中所有键的加权值的总和(此示例:A, B, C),由列表中的最后一个数字加权(list[-1] )?

例如,这将是:

的总和
(2/15)*3 + (4/15)*5 + (9/15)*10 = 7.73

其中15是2,4,9的总和。

目前我正在创建太多只能遍历字典的变量。我确信有一种快速有效的Python方法。

2 个答案:

答案 0 :(得分:2)

使用(2/15)*3 + (4/15)*5 + (9/15)*10(2*3 + 4*5 + 9*10)/15相同的事实,您不必预先计算总数,因此您可以在{{1}的dict的一次传递中执行此操作但也许它不是那么可读。

将dict变成一系列元组:

reduce

或者没有中间生成器并使用初始值(可能是最快的):

>>> d = {A:['asdasd',2,3], B:['asdasd',4,5], C:['rgerg',9,10]}
>>> from functools import reduce    # Py3
>>> x,y = reduce(lambda t, e: (t[0]+e[0], t[1]+e[1]), ((a*b, a) for _,a,b in d.values()))
>>> x/y   # float(y) in Py2
7.733333333333333

或者你可以压缩结果并总结:

>>> x,y = reduce(lambda t, e: (t[0]+e[1]*e[2], t[1]+e[1]), d.values(), (0,0))
>>> x/y   # float(y) in Py2
7.733333333333333

或者你可以做@ranlot建议但我会避开中间名单:

>>> x,y = (sum(x) for x in zip(*((a*b, a) for _,a,b in d.values())))
>>> x/y   # float(y) in Py2
7.733333333333333

虽然这似乎比上述任何一个都要慢一些。

答案 1 :(得分:1)

myDict = {'A':['asdasd', 2, 3], 'B':['asdasd', 4, 5], 'C':['rgerg', 9, 10]}
normConst = sum([dict[x][-2] for x in myDict])
sum([dict[x][-1]*dict[x][-2] / float(normConst) for x in myDict])