什么';这是合并两个字典的最具python风格的方法,但要使值成为平均值?

什么';这是合并两个字典的最具python风格的方法,但要使值成为平均值?,python,dictionary,Python,Dictionary,最好的方法是什么?这里有一种方法: d1 = { 'apples': 2, 'oranges':5 } d2 = { 'apples': 1, 'bananas': 3 } result_dict = { 'apples': 1.5, 'oranges': 5, 'bananas': 3 } 还有另一种方式: result = dict(d2) for k in d1: if k in result: result[k] = (result[k] + d1[k])

最好的方法是什么?

这里有一种方法:

d1 = { 'apples': 2, 'oranges':5 }
d2 = { 'apples': 1, 'bananas': 3 }


result_dict = { 'apples': 1.5, 'oranges': 5, 'bananas': 3 }
还有另一种方式:

result = dict(d2)
for k in d1:
    if k in result:
        result[k] = (result[k] + d1[k]) / 2.0
    else:
        result[k] = d1[k]

这适用于任何数量的词典:

result = dict(d1)
for (k,v) in d2.items():
    result[k] = (result.get(k,v) + v) / 2.0
更新:@mhyfritz展示了一种将3行减为一行的方法

dicts = ({"a": 5},{"b": 2, "a": 10}, {"a": 15, "b": 4})
keys = set()
averaged = {}
for d in dicts:
    keys.update(d.keys())
for key in keys:
    values = [d[key] for d in dicts if key in d]
    averaged[key] = float(sum(values)) / len(values)
print averaged
# {'a': 10.0, 'b': 3.0}

你的问题是以最“蟒蛇式”的方式提出的

我认为对于这样一个问题,Pythonic的方法是非常清楚的。有很多方法可以实现这个问题的解决方案!如果你真的只有两个DICT,那么假设这是很好的解决方案,因为它们更简单(因此更容易阅读和维护)。然而,拥有通用解决方案通常是一个好主意,因为这意味着您不需要在其他情况下复制大部分逻辑,例如,您有3个字典

作为附录,Phantom的答案很好,因为它使用了大量Python的特性,使解决方案具有可读性。我们看到一个列表:

dicts = ({"a": 5},{"b": 2, "a": 10}, {"a": 15, "b": 4})
averaged = {}
keys = set().union(*dicts)
for key in keys:
    values = [d[key] for d in dicts if key in d]
    averaged[key] = float(sum(values)) / len(values)
print averaged
使用Python非常有用的
set
类型:

[d[key] for d in dicts if key in d]
一般来说,很好地使用Python的类型方法和全局变量:

keys = set()
keys.update(d.keys())
思考并实现一个算法来解决这个问题是一回事,但是利用语言的力量使它变得如此优雅和可读是大多数人认为的“Pythonic”


(我会使用Phantom的解决方案)

计数器和一些生成器在这种情况下很有用

一般情况:

d.keys()
keys.update( ... )
keys.update
len(values)

+1.作为旁注,您可以编写
keys=set().union(*dicts)
。这利用了这样一个事实,即
dict
(仅)的
集合包含
dict
的键。@mhyfritz:嘿,这太好了顺便说一句:@user也在答案中工作吗?很好的逻辑解决方案伙伴,当你阅读代码时,你可以理解它在做什么。我建议使用
d2.copy()
而不是
dict(d2)
。它稍微快一点(对于一个只有很少项目的dict来说,速度更快,大约是它的两倍),而且在我看来更明显。我也会乘0.5而不是除法。
>>> d1 = { 'apples': 2, 'oranges':5 }
>>> d2 = { 'apples': 1, 'bananas': 3 }
>>> all_d=[d1,d2]
>>> from collections import Counter
>>> counts=Counter(sum((d.keys() for d in all_d),[]))
>>> counts
Counter({'apples': 2, 'oranges': 1, 'bananas': 1})
>>> s=lambda k: sum((d.get(k,0) for d in all_d))
>>> result_set=dict(((k,1.0*s(k)/counts[k]) for k in counts.keys()))
>>> result_set
{'apples': 1.5, 'oranges': 5.0, 'bananas': 3.0}
d1 = { 'apples': 2, 'oranges':5 }
d2 = { 'apples': 1, 'bananas': 3, 'oranges':0 }
dicts = [d1, d2]

result_dict = {}

for dict in dicts:
    for key, value in dict.iteritems():
        if key in result_dict:
            result_dict[key].append(value)
        else:
            result_dict[key] = [value]

for key, values in result_dict.iteritems():
    result_dict[key] = float(sum(result_dict[key])) / len(result_dict[key])

print result_dict