How to operate on nested dictionary in python 3.x?

后端 未结 5 697
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-29 14:47

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:

相关标签:
5条回答
  • 2021-01-29 15:02
    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
    
    0 讨论(0)
  • 2021-01-29 15:05

    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)
    
    0 讨论(0)
  • 2021-01-29 15:08

    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)
    
    0 讨论(0)
  • 2021-01-29 15:19

    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 :)

    0 讨论(0)
  • 2021-01-29 15:28

    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)
    
    0 讨论(0)
提交回复
热议问题