Hanny
Hanny

Reputation: 2159

Combine dictionary entries into new dictionary entry based on similar keys with python

I've got the following dictionaries:

{'grade': '7', 'current_student_sum': 1559}
{'grade': '8', 'current_student_sum': 1638}
{'grade': 'KF', 'current_student_sum': 1588}
{'grade': 'KA', 'current_student_sum': 1588}
{'grade': 'PA', 'current_student_sum': 366}
{'grade': 'PF', 'current_student_sum': 54}
{'grade': 'PP', 'current_student_sum': 384}

I am trying to find the cleanest way to loop through there and sum any grade starting with 'P' (and do the same with 'K')

End result:

I am trying to get the dictionaries to look like this:

{'grade': '7', 'current_student_sum': 1559}
{'grade': '8', 'current_student_sum': 1638}
{'grade': 'K', 'current_student_sum': 3176}
{'grade': 'P', 'current_student_sum': 816}

An alternative solution would be if it was like this:

{
'grade': 'K', 'student_sum': 3176,
'grade': 'P', 'student_sum': 816,
..etc
}

I've seen the methods using Counter but that is only if the key's are matching across dictionaries.

These don't necessarily have to be dictionaries if making them lists or something makes it a little easier.

Upvotes: 0

Views: 41

Answers (3)

jpp
jpp

Reputation: 164693

A vectorised solution is possible with 3rd party Pandas:

import pandas as pd

L = [{'grade': '7', 'current_student_sum': 1559},
     {'grade': '8', 'current_student_sum': 1638},
     {'grade': 'KF', 'current_student_sum': 1588},
     {'grade': 'KA', 'current_student_sum': 1588},
     {'grade': 'PA', 'current_student_sum': 366},
     {'grade': 'PF', 'current_student_sum': 54},
     {'grade': 'PP', 'current_student_sum': 384}]

df = pd.DataFrame(L)

res = df.groupby(df['grade'].str[0])['current_student_sum'].sum()\
        .reset_index().to_dict('records')

print(res)

[{'current_student_sum': 1559, 'grade': '7'},
 {'current_student_sum': 1638, 'grade': '8'},
 {'current_student_sum': 3176, 'grade': 'K'},
 {'current_student_sum': 804, 'grade': 'P'}]

Upvotes: 0

Ajax1234
Ajax1234

Reputation: 71451

You can use itertools.groupby:

import itertools
d = [{'grade': '7', 'current_student_sum': 1559}, {'grade': '8', 'current_student_sum': 1638}, {'grade': 'KF', 'current_student_sum': 1588},{'grade': 'KA', 'current_student_sum': 1588}, {'grade': 'PA', 'current_student_sum': 366}, {'grade': 'PF', 'current_student_sum': 54}, {'grade': 'PP', 'current_student_sum': 384}]
new_d = [[a, list(b)] for a, b in itertools.groupby(sorted(d, key=lambda x:x['grade'][0]), key=lambda x:x['grade'][0])]
final_grade = [{'grade':a, 'current_student_sum':sum(i['current_student_sum'] for i in b)} for a, b in new_d]

Output:

[{'grade': '7', 'current_student_sum': 1559}, 
 {'grade': '8', 'current_student_sum': 1638}, 
 {'grade': 'K', 'current_student_sum': 3176}, 
 {'grade': 'P', 'current_student_sum': 804}]

Upvotes: 0

Rakesh
Rakesh

Reputation: 82765

Using collections.defaultdict

Ex:

import collections
res = collections.defaultdict(int)
data = [{'grade': '7', 'current_student_sum': 1559},
{'grade': '8', 'current_student_sum': 1638},
{'grade': 'KF', 'current_student_sum': 1588},
{'grade': 'KA', 'current_student_sum': 1588},
{'grade': 'PA', 'current_student_sum': 366},
{'grade': 'PF', 'current_student_sum': 54},
{'grade': 'PP', 'current_student_sum': 384}]

for i in data:
    res[i['grade'][0]] += i["current_student_sum"]

res = [{'grade':k, 'current_student_sum':v}  for k,v in res.items()]
print(res)

Output:

[{'current_student_sum': 1638, 'grade': '8'},
 {'current_student_sum': 3176, 'grade': 'K'},
 {'current_student_sum': 1559, 'grade': '7'},
 {'current_student_sum': 804, 'grade': 'P'}]

Upvotes: 2

Related Questions