使用python基于相似键将字典条目组合为新的字典条目

时间:2018-07-10 14:45:47

标签: python dictionary

我有以下字典:

{'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}

我正在尝试找到一种最干净的方法来遍历那里,并对以'P'开头的所有成绩求和(并以'K'进行同样的操作)

最终结果:

我正在尝试使字典看起来像这样:

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

另一种解决方案是:

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

我已经看过使用Counter的方法,但这仅在键在各个字典中都匹配的情况下才会出现。

如果将它们列为列表或某些使其变得更容易的词,则不一定必须作为字典。

3 个答案:

答案 0 :(得分:2)

使用collections.defaultdict

例如:

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)

输出:

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

答案 1 :(得分:0)

您可以使用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]

输出:

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

答案 2 :(得分:0)

第三方熊猫可以使用矢量化解决方案:

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'}]