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

How to use dictionary values to calculate sum of weighted values without explicitly defined weights?

例如我有一个字典如下:

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

我怎样才能得到一个数字,它基本上是字典中所有键的加权值的总和(这个例子:A, B, C)由列表中的最后一个数字加权(list[-1])?

例如,这将是以下总和:

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

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

目前我正在创建太多的变量,这些变量只是遍历字典。我确信有一种快速高效的 Python 方法可以做到这一点。

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])

利用 (2/15)*3 + (4/15)*5 + (9/15)*10(2*3 + 4*5 + 9*10)/15 相同的事实,您不必 pre-calculate 总数,因此您可以在 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

或者您可以压缩结果并求和:

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

或者您可以按照@ranlot 的建议进行操作,但我会避免使用中间列表:

>>> sum(a*b for _,a,b in d.values())/sum(a for _,a,b in d.values())
7.733333333333333

虽然这似乎比上面的任何一个都慢一点。