获取字典列表中的平均值的最佳方法

2024-04-18 23:24:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一份目录如下:

rois = [{'player': 'kraftvk', 'over': {1.5: 67.97, 1.75: 51.005}, 'under': {1.5: -77.97, 1.75: -59.12}}, {'player': 'meltosik', 'over': {1.5: 61.635, 1.75: 37.455}, 'under': {1.5: -71.635, 1.75: -44.765}}]

我想得到每本字典的平均数。预期产出:

d = {'over': {1.5: 64.80, 1.75: 44.23}, 'under': {1.5: -74.80, 1.75: -51.9425}}

因此,映射每个字典中每个键的值,并对它们进行平均,然后放入一个新字典

不确定这样做的最佳/最具Python风格的方式

第一个列表的结构与第二个列表的结构相同,因此可以执行以下操作:

d = {'over': {}, 'under': {}}


for k,v in rois[0].items():
    if k != 'player':
        for quote, roi in rois[0][k].items():
            if k == 'over':
                d[k][quote] = (roi + rois[1]['over'][quote])/2
            if k == 'under':
                d[k][quote] = (roi + rois[1]['under'][quote])/2

这似乎有点过头了,可能还有比这更优雅的解决方案

谢谢你的帮助


Tags: in目录列表forif字典items结构
3条回答

您可以使用Counter查找所有dict值的总和,然后最后将其除以列表的长度以获得平均值

from collections import Counter

cover = Counter(); cunder = Counter()
for d in rois:
    cover.update(d['over'])
    cunder.update(d['under'])

>>> l = len(rois)
>>> res = {}
>>> res['over'] = {k:round(v/l,2) for k,v in cover.items()}
>>> res['under'] = {k:round(v/l,2) for k,v in cunder.items()}
>>> 
>>> res
{'over': {1.5: 64.8, 1.75: 44.23}, 'under': {1.5: -74.8, 1.75: -51.94}}
d = {'over': [], 'under': []}


rois = [{'player': 'kraftvk', 'over': {1.5: 67.97, 1.75: 51.005}, 'under': {1.5: -77.97, 1.75: -59.12}}, {'player': 'meltosik', 'over': {1.5: 61.635, 1.75: 37.455}, 'under': {1.5: -71.635, 1.75: -44.765}}]

# Collecting players 'over' and 'under' dictionaries
for player_dict in rois:
    d['over'].append(player_dict['over'])
    d['under'].append(player_dict['under'])

print(d)

s = {'over': {}, 'under': {}}

def average_dicts(dicts):
    sum_dict = {}
    # Going over the ['over' and 'under'] dictionaries collection
    for d in dicts:
        # Going over the [{1.5 : value_1, 1.75 : value_2}] dictionary, that's under either ['over' and 'under'] dictionaries
        for k, v in d.items():
            # Summing all values of either [ 1.5, 1.75]
            if k not in sum_dict.keys():
                sum_dict[k] = 0
            sum_dict[k] += d.get(k,0)
    # Dividing sum by number of dictionaries to get average
    for k, v in sum_dict.items():
        sum_dict[k] = v / len(dicts)
    return sum_dict

s['over'] = average_dicts(d['over'])
s['under'] = average_dicts(d['under'])

print(s)

可以争论的是,它们是否更“Pythonic”,但字典理解是一种选择。这里有一个dict理解和内置zip()map()函数的方法

>>> rois = [{'player': 'kraftvk', 'over': {1.5: 67.97, 1.75: 51.005}, 'under': {1.5: -77.97, 1.75: -59.12}}, {'player': 'meltosik', 'over': {1.5: 61.635, 1.75: 37.455}, 'under': {1.5: -71.635, 1.75: -44.765}}]
>>> d1 = { key : zip(*[ elem[key].values() for elem in rois]) for key in rois[0].keys() if key != "player" }
>>> d2 = { key : value.keys() for key,value in rois[0].items() if key != "player" }
>>> avg = lambda l : round(sum(l)/float(len(l)), 2)
>>> d3 = { key : map(avg, value) for key, value in d1.items() }
>>> d = { key : dict(zip(value, d3[key])) for key, value in d2.items() }
>>> d
{'under': {1.5: -74.8, 1.75: -51.94}, 'over': {1.5: 64.8, 1.75: 44.23}}

相关问题 更多 >