You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于student_id对含嵌套字典列表的字典列表分组聚合?

按学生ID聚合历年成绩数据

问题描述

我有如下格式的字典列表:

d = [
{'value': [{'student_id': 45522, 'marks': 75}, {'student_id': 70515, 'marks': 80}],'year':2001},
{'value': [{'student_id': 45522, 'marks': 35}, {'student_id': 70515, 'marks': 90}],'year':2002},
{'value': [{'student_id': 45522, 'marks': 60}, {'student_id': 70515, 'marks': 89}],'year':2003}
]

希望将数据按学生ID聚合,得到每个学生的历年年份和对应成绩的列表:

student_marks_data = [
                      {"student_id":45522, "years":[2001,2002,2003], "marks":[75,35,60]},
                      {"student_id":70515, "years":[2001,2002,2003], "marks":[80,90,89]}
                     ]

注:你提供的期望结果中45522的marks字段有个30,应该是笔误,这里按原始数据的35处理。

我了解过itertools库,但不清楚如何用它实现这个需求。

解决方案

方法1:用普通字典直接聚合(直观高效)

这种方法不需要额外库,直接遍历原始数据,逐步收集每个学生的年份和成绩:

d = [
{'value': [{'student_id': 45522, 'marks': 75}, {'student_id': 70515, 'marks': 80}],'year':2001},
{'value': [{'student_id': 45522, 'marks': 35}, {'student_id': 70515, 'marks': 90}],'year':2002},
{'value': [{'student_id': 45522, 'marks': 60}, {'student_id': 70515, 'marks': 89}],'year':2003}
]

# 用字典存储每个学生的信息,key为student_id
student_dict = {}
for entry in d:
    current_year = entry['year']
    for student_info in entry['value']:
        sid = student_info['student_id']
        current_marks = student_info['marks']
        
        if sid not in student_dict:
            # 首次遇到该学生,初始化数据结构
            student_dict[sid] = {
                'student_id': sid,
                'years': [],
                'marks': []
            }
        # 追加当前年份和成绩
        student_dict[sid]['years'].append(current_year)
        student_dict[sid]['marks'].append(current_marks)

# 把字典的值转为列表,就是最终结果
student_marks_data = list(student_dict.values())
print(student_marks_data)

方法2:用itertools.groupby实现

如果一定要用itertools.groupby,需要先将数据展开并排序(因为groupby仅对连续相同键的元素分组):

from itertools import groupby

d = [
{'value': [{'student_id': 45522, 'marks': 75}, {'student_id': 70515, 'marks': 80}],'year':2001},
{'value': [{'student_id': 45522, 'marks': 35}, {'student_id': 70515, 'marks': 90}],'year':2002},
{'value': [{'student_id': 45522, 'marks': 60}, {'student_id': 70515, 'marks': 89}],'year':2003}
]

# 步骤1:展开所有学生记录,给每条记录添加year字段
flattened_records = []
for entry in d:
    year = entry['year']
    for student in entry['value']:
        flattened_records.append({
            'student_id': student['student_id'],
            'year': year,
            'marks': student['marks']
        })

# 步骤2:按student_id排序,确保相同ID的记录连续
sorted_records = sorted(flattened_records, key=lambda x: x['student_id'])

# 步骤3:分组并聚合年份和成绩
student_marks_data = []
for student_id, group in groupby(sorted_records, key=lambda x: x['student_id']):
    years = []
    marks = []
    for item in group:
        years.append(item['year'])
        marks.append(item['marks'])
    student_marks_data.append({
        'student_id': student_id,
        'years': years,
        'marks': marks
    })

print(student_marks_data)

两种方法都能得到目标结果,第一种更直接高效,第二种适合需要使用itertools的场景。

内容的提问来源于stack exchange,提问作者kishanparmar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:09:30