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

Python嵌套字典反向过滤 按科目提取参考学生列表

问题场景

现有存储学生考试成绩的嵌套字典dico,外层键为学生姓名,内层键为考试科目、值为对应考试分数,结构示例:

dico = {
    "Pierre":{
        'Math':16,
        'Chimie':9,
        'Dessin':18,
        'Electronic':20,
        'Info':14,
    },
    "Jean":{
        'Physics':10,
        'Chimie':20,
        'Dessin':13,
        'Electronic':16,
        'Info':17,
    },
    "Giovani":{
        'Math':16,
        'Physics':14,
        'Chimie':13,
        'Dessin':14,
        'Electronic':17,
        'Info':12,
    }
    # 其余学生数据省略
}

需要实现反向聚合:提取参加每门考试的所有学生,输出「科目: 参考学生列表/集合」格式,预期效果示例:

{
    'Math': ['Pierre', 'Giovani'], 
    'Physics': ['Jean', 'Giovani']
    # 其余科目对应参考学生
}

原有尝试代码运行失败,无法得到预期结果:

exam_set = [{k:v for (k, v) in i.items()}
                for i in dico if i.get(v) != 0]
原有代码问题
  • 外层遍历逻辑错误:直接for i in dico拿到的i是学生姓名字符串,不是对应科目的成绩字典,无法调用.items()方法
  • 变量未定义:判断条件中的v没有提前声明,会直接抛出名称错误
  • 聚合方向错误:代码尝试按学生维度生成字典,和「按科目聚合学生」的需求完全相反
正确实现方案

方法1:基础循环实现(无依赖,可读性最高)

先初始化结果空字典,遍历每个学生的所有考试科目,将学生姓名追加到对应科目的列表中,支持过滤0分(缺考)记录:

result = {}
for student, score_map in dico.items():
    for subject, score in score_map.items():
        # 过滤0分记录,不需要可以删掉这个判断
        if score == 0:
            continue
        # 科目第一次出现时初始化空列表
        if subject not in result:
            result[subject] = []
        result[subject].append(student)

如果需要去重的集合格式,把列表换成集合即可:

result = {}
for student, score_map in dico.items():
    for subject, score in score_map.items():
        if score == 0:
            continue
        if subject not in result:
            result[subject] = set()
        result[subject].add(student)

方法2:用defaultdict简化逻辑

用标准库collections的defaultdict可以省去手动判断科目是否存在的步骤,代码更简洁:

from collections import defaultdict

result = defaultdict(list)
for student, score_map in dico.items():
    for subject, score in score_map.items():
        if score != 0:
            result[subject].append(student)

# 如果需要转成普通原生字典,加一行 result = dict(result) 即可

方法3:字典推导式一行实现

如果偏好推导式写法,可以按科目维度遍历,嵌套推导式筛选对应参考学生:

result = {
    subject: [
        stu for stu, score_map in dico.items() 
        if subject in score_map and score_map[subject] != 0
    ]
    for all_subjects in dico.values() 
    for subject in all_subjects
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 10:06:35