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

如何在Python中高效分组课程对象的学生分数数据

高效实现课程分数数据按学生-分数分组的方案

这个需求本质是多层分组聚合:先按学生分组,再按分数分组,最后收集对应分数的课程列表。下面给出两种高效的实现方式,都是线性时间复杂度,处理大量数据也没问题。

准备工作:模拟课程对象

首先我们先把你的课程对象用代码模拟出来,方便测试:

class Course:
    def __init__(self, name, records):
        self.name = name
        self.records = records

# 示例课程
c1 = Course("c1", {"student1": 100, "student2": 90})
c2 = Course("c2", {"student1": 100, "student2": 40, "student3": 80})
# 把所有课程放到一个列表里统一处理
courses = [c1, c2]

方案一:用collections.defaultdict简化代码(推荐)

利用Python标准库的defaultdict可以省去手动判断键是否存在的繁琐步骤,代码简洁且高效:

from collections import defaultdict

# 初始化嵌套字典:学生 -> {分数: [课程名称列表]}
result = defaultdict(lambda: defaultdict(list))

for course in courses:
    course_name = course.name
    # 遍历当前课程的所有学生分数记录
    for student, score in course.records.items():
        # 直接追加课程名称,defaultdict会自动初始化不存在的键
        result[student][score].append(course_name)

# 可选:将嵌套的defaultdict转换为普通字典(如果需要严格匹配目标格式)
final_result = {student: dict(scores) for student, scores in result.items()}
print(final_result)

输出结果完全符合你的需求:

{
 'student1': {100: ['c1', 'c2']},
 'student2': {90: ['c1'], 40: ['c2']},
 'student3': {80: ['c2']}
}

方案说明

  • defaultdict(lambda: defaultdict(list))创建了一个两层的默认字典:第一层的键是学生名,对应的值是另一个默认字典;第二层的键是分数,对应的值是列表,用来存课程名称。
  • 整个过程是线性遍历,每个分数记录只处理一次,时间复杂度为O(N)(N是所有课程的学生记录总数),效率拉满。

方案二:不依赖标准库,手动实现字典初始化

如果不想导入collections,可以手动判断键是否存在,逻辑和方案一完全一致,只是代码稍长:

result = {}

for course in courses:
    course_name = course.name
    for student, score in course.records.items():
        # 初始化学生对应的字典
        if student not in result:
            result[student] = {}
        # 初始化分数对应的课程列表
        if score not in result[student]:
            result[student][score] = []
        # 添加当前课程名称
        result[student][score].append(course_name)

print(result)

这个版本同样是O(N)的时间复杂度,适合对依赖有严格限制的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 20:47:48