Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Sum the value in the list of dictionary based on the same key

I have a list of dictionaries which looks like:

data = [{'stat3': '5', 'stat2': '4', 'player': '1'}, 
        {'stat3': '8', 'stat2': '1', 'player': '1'}, 
        {'stat3': '6', 'stat2': '1', 'player': '3'}, 
        {'stat3': '3', 'stat2': '7', 'player': '3'}]

And I want to get a nested dictionary whose keys are the value from the key('player') and whose values are dictionaries of aggregated stats.

The output should:

{'3': {'stat3': 9, 'stat2': 8, 'player': '3'}, 
 '1': {'stat3': 13, 'stat2': 5, 'player': '1'}}

The following is my code:

from collections import defaultdict
result = {}
total_stat = defaultdict(int)

for dict in data:
    total_stat[dict['player']] += int(dict['stat3'])  
    total_stat[dict['player']] += int(dict['stat2']) 
total_stat = ([{'player': info, 'stat3': total_stat[info],
                'stat2': total_stat[info]} for info in 
                 sorted(total_stat, reverse=True)])
for item in total_stat:       
    result.update({item['player']: item})
print(result)

However, I got this:

{'3': {'player': '3', 'stat3': 17, 'stat2': 17}, 
 '1': {'player': '1', 'stat3': 18, 'stat2': 18}}

How could I make it right? Or are there other approaches?

like image 373
supremepuff Avatar asked Dec 11 '17 17:12

supremepuff


People also ask

How do you sum the values of each key in a Python dictionary?

It is pretty easy to get the sum of values of a python dictionary. You can first get the values in a list using the dict. values(). Then you can call the sum method to get the sum of these values.

How do you sum all values in a list Python?

Python provides an inbuilt function sum() which sums up the numbers in the list. Syntax: sum(iterable, start) iterable : iterable can be anything list , tuples or dictionaries , but most importantly it should be numbers. start : this start is added to the sum of numbers in the iterable.


2 Answers

Your data is rather a DataFrame, a natural pandas solution is :

In [34]: pd.DataFrame.from_records(data).astype(int).groupby('player').sum().T.to_dict()

Out[34]: {1: {'stat2': 5, 'stat3': 13}, 3: {'stat2': 8, 'stat3': 9}}
like image 131
B. M. Avatar answered Sep 28 '22 00:09

B. M.


Just use a more nested default-factory:

>>> total_stat = defaultdict(lambda : defaultdict(int))
>>> value_fields = 'stat2', 'stat3'
>>> for datum in data:
...     player_data = total_stat[datum['player']]
...     for k in value_fields:
...         player_data[k] += int(datum[k])
...
>>> from pprint import pprint
>>> pprint(total_stat)
defaultdict(<function <lambda> at 0x1023490d0>,
            {'1': defaultdict(<class 'int'>, {'stat2': 5, 'stat3': 13}),
             '3': defaultdict(<class 'int'>, {'stat2': 8, 'stat3': 9})})
like image 35
juanpa.arrivillaga Avatar answered Sep 28 '22 00:09

juanpa.arrivillaga