问题
I am stuck with this question, can you solve the challenge? Here we go!
We represent scores of players across a sequence of matches in a two level dictionary as follows:
{'match1':{'player1':57, 'player2':38}, 'match2':{'player3':9, 'player1':42}, 'match3':{'player2':41, 'player4':63, 'player3':91}}
Each match is identified by a string, as is each player. The scores are all integers. The names associated with the matches are not fixed (here they are 'match1','match2','match3'), nor are the names of the players. A player need not have a score recorded in all matches.
Define a Python function orangecap(d)
that reads a dictionary d of this form and identifies the player with the highest total score. Your function should return a pair (playername,topscore) where playername is a string, the name of the player with the highest score, and topscore is an integer, the total score of playername.
The input will be such that there are never any ties for highest total score.
For instance:
>>> orangecap({'match1':{'player1':57, 'player2':38}, 'match2':{'player3':9, 'player1':42}, 'match3':{'player2':41, 'player4':63, 'player3':91}})
('player3', 100)
>>> orangecap({'test1':{'Ashwin':84, 'Kohli':120}, 'test2':{'ashwin':59, 'Pujara':42}})
('Kohli', 120)
回答1:
with pandas
it's really easy:
In [78]: d
Out[78]:
{'match1': {'player1': 57, 'player2': 38},
'match2': {'player1': 42, 'player3': 9},
'match3': {'player2': 41, 'player3': 91, 'player4': 63}}
In [79]: pd.DataFrame(d).sum(axis=1).idxmax()
Out[79]: 'player3'
In [80]: pd.DataFrame(d).sum(axis=1).max()
Out[80]: 100.0
First convert it to a DataFrame, then sum over the columns, and find the max :)
回答2:
You can easily use a running counter to count the scores first:
from collections import Counter
def orangecap(d):
total = Counter()
for match_result in d.values():
total.update(match_result)
return total.most_common(1)[0]
Here Counter.update(iterable) will increment the counters for the players mentioned. Counter.most_common(n) specifies we want the first most common element. This will return a list and we pick the first tuple.
>>> orangecap(d)
('player3', 100)
回答3:
I would suggest using Willem Van Onsem answer, but if you don't want to import then here is an alternative.
data = {
'match1': {
'player1': 57,
'player2': 38},
'match2': {
'player3': 9,
'player1': 42},
'match3': {
'player2': 41,
'player4': 63,
'player3': 91}
}
def orangecap(data):
totals = {}
for d in data.values():
for k, v in d.items():
totals[k] = totals.setdefault(k, 0) + v
return max(totals.items(), key = lambda t:t[1])
>>> orangecap(data)
('player3', 100)
回答4:
import operator
def orangecap(d):
players = {}
for dict in d.values():
for player in dict:
if player in players:
players[player] += dict[player]
else:
players[player] = dict[player]
scores = sorted(players.items(), key = operator.itemgetter(1), reverse = True)
return scores[0]
#Credits to Willem Van Onsem for his various suggestions
回答5:
Some code golfing with functools.reduce:
from functools import reduce
from collections import Counter
v = reduce(lambda x, y: x.update(y) or x, d.values(), Counter()).most_common(1)[0])
print(v)
# ('player3', 100)
来源:https://stackoverflow.com/questions/42444903/how-to-operate-on-nested-dictionary-in-python-3-x