'Find the sum of values within the values of a nested Dictionary
This is a question based on nested dictionaries.
We are given a nested dictionary wherein in the outer dictionary, the name of the match is mentioned and the value for the matches is another dictionary with it's key and values respectively and the name of the function is orangecap(d)
which accepts a dictionary in the below format.
Here's the sample.
d = {'match1':{'player1':57, 'player2':38}, 'match2':{'player3':9, 'player1':42}, 'match3':{'player2':41, 'player4':63, 'player3':91}}
So I would like to search by the player key and calculate the total sum for each player and return the largest sum.
So the output needs to be ('player3', 100)
This is what i have tried so far but to no avail:
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))
Solution 1:[1]
This is a slightly modified answer taken from a previous answer of mine.
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]
Sample output:
>>> d = {'match1':{'player1':57, 'player2':38}, 'match2':{'player3':9, 'player1':42}, 'match3':{'player2':41, 'player4':63, 'player3':91}}
>>> print find_totals(d)
('player3', 100)
So what's going on with your code?, Let's examine the algorithm:
Firstly, you iterate through the items (keys/values) of d
. This is fine, as you're trying to traverse a nested dictionary structure. However instead of traversing the inner most structure using the second for
loop (iterating over value
, instead of d
), you instead traverse d
again.
value
is now simply a tuple of key/value stores in d
, rather than the nested dictionary. d[key]
is simply the value mapped to the match keys. So how then could a value
be in the list of keys -> d.keys()
Your if
condition never evaluates to true
. Despite this, you end up short-circuiting the entire iteration to the return
statement after only two iterations. Which neither returns the correct player (d[key]
is the nested dictionary), and max
takes an iterable argument, not an int.
You should learn more about basic control flow, data structures, and algorithm design. I would suggest Google's excellent python series.
Solution 2:[2]
Something like this should work:
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]
This creates a dictionary (players
) containing the player's total score. Then it sorts the items from the dictionary using the score and returns the highest.
Solution 3:[3]
Because someone had to do it... Here's a one-liner.
EDIT: no longer a one liner because I realised the player was also meant to be returned. So it's now a one-liner in a function.
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)
Solution 4:[4]
Here's a possible solution:
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))
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Community |
Solution 2 | FamousJameous |
Solution 3 | |
Solution 4 |