在嵌套字典的值中找到数值的总和

3

这是一个关于嵌套字典的问题。

我们得到了一个嵌套字典,其中外层字典中提到了比赛名称并且该比赛的值为另一个字典,键和值分别为其函数名是orangecap(d),接受以下格式的字典。

以下是样例。

d = {'match1':{'player1':57, 'player2':38}, 'match2':{'player3':9, 'player1':42}, 'match3':{'player2':41, 'player4':63, 'player3':91}}

我希望能够通过球员关键字搜索并计算每个球员的总和,返回最大的总和。
所以输出应该是('player3', 100)
这是我目前尝试过但无效的代码:
def orangecap(d):
  total=0
  for key,value in d.items():
      for value in d.items():
          if d[key] in d.keys():
              total = total+d[value]
          return(d[key],max(total))
4个回答

3

这是一个稍作修改的答案,摘自我的之前的回答。

def find_totals(d):
    total = {}
    for match, results in d.items():
        for player, score in results.items():
            total[player] = total.get(player, 0) + score
    highest_score = max(total, key=total.get)
    return highest_score, total[highest_score]

输出示例:

>>> d = {'match1':{'player1':57, 'player2':38}, 'match2':{'player3':9, 'player1':42}, 'match3':{'player2':41, 'player4':63, 'player3':91}}
>>> print find_totals(d)
('player3', 100)

那么你的代码出了什么问题呢?让我们来看一下算法:
首先,你遍历字典 d 的项(键/值)。这是可以的,因为你正试图遍历一个嵌套的字典结构。然而,你在第二个 for 循环中并没有遍历最内部的结构(遍历 value,而不是 d),而是再次遍历了 d
现在,value 只是在 d 中存储的 键/值 对的一个 元组,而不是嵌套的字典。 d[key] 只是映射到匹配键的值。那么,一个 value 怎么可能在键列表 -> d.keys() 中呢?你的 if 条件从未评估为 true。尽管如此,你最终在只有 两个 迭代后就将整个迭代截断到 return 语句。它既没有返回正确的玩家(d[key] 是嵌套的字典),也没有按照预期调用 max,因为它需要一个可迭代的参数而不是一个整数。
你应该学习更多关于基本的控制流、数据结构和算法设计的知识。我建议你看一下谷歌出品的优秀的 Python 系列教程

请问您能告诉我我的代码哪里出了问题吗? - Dhruv Marwha
@DhruvMarwha,如果您认为我已经回答了您的问题,请随意将其标记为已回答。 - ospahiu

1

这样做应该可以:

def orangecap(d):
    players = {}
    for match, scores in d.iteritems():
        for player, score in scores.iteritems():
            if player not in players:
                players[player] = score
            else:
                players[player] += score
    return sorted(players.items(), key=lambda x: x[1])[-1]

这段代码创建了一个包含玩家总得分的字典(players),然后按照得分对字典中的项目进行排序,并返回最高得分。

0
这是一个可能的解决方案:
from collections import defaultdict

data = {
    'match1': {'player1': 57, 'player2': 38},
    'match2': {'player3': 9, 'player1': 42},
    'match3': {'player2': 41, 'player4': 63, 'player3': 91}
}


def orangecap(d):
    result = defaultdict(int)
    for k, v in data.items():
        for k1, v1 in v.items():
            result[k1] += v1

    return sorted(result.items(), key=lambda x: x[1])[-1]

print(orangecap(data))

你可以使用 defaultdict(int) 来代替 lambda 表达式,这样就可以将默认值设置为 0 :) - Karin

0
因为总得有人来做这件事情... 这是一行代码。
编辑:不再是一行代码,因为我意识到玩家也需要被返回。所以现在它是一个函数中的一行代码。
def total_score(*, match_results: dict, player_name: str):
    return player_name, sum(score for player_scores in match_results.values() 
                                  for player, score in player_scores.items() 
                                  if player == player_name)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接