如何处理字典式学生数据库的课程成绩更新与重复课程过滤?
学生成绩数据库问题解决方案
问题描述
我用字典搭建学生数据库,键为学生姓名,对应值是由「课程名称+成绩」组成的元组列表,一个学生可修读多门课程。目前遇到两个核心问题:
- 元组不可变,不知道如何替换特定课程的成绩;
- 学生重修课程时,需要实现「新成绩高于原有成绩才更新,低于则不更新」的逻辑,同时要排除成绩为0的课程。现在无法阻止已有课程的低分记录重复添加,比如
Introduction to Programming课程重复出现了低分2的情况。
现有代码
def add_student(students: dict, name: str): if len(students) == 0: students[name] = [()] if name not in students: students[name] = [()] return students def print_student(students: dict, name: str): if name not in students: print(f"{name}: no such person in the database") elif students[name] == [()]: print(f"{name}:\n no completed courses") else: print(f"{name}:\n {len(students[name])} completed courses:") for i in range(len(students[name])): print(f" {students[name][i][0]} {students[name][i][1]}") sum_course = 0 for i in range(len(students[name])): sum_course += students[name][i][1] print(f" average grade: {sum_course / len(students[name])}") return def add_course(students: dict, name: str, course: tuple): if name not in students: print(f"{name}: no such person in the database") elif students[name] == [()] and course[1] != 0: students[name].append(course) students[name].remove(()) elif course[0] not in students and course[1] !=0: students[name].append(course) return students if __name__ == "__main__": students = {} add_student(students, "Peter") print() add_course(students, "Peter", ("Introduction to Programming", 3)) add_course(students, "Peter", ("Advanced Course in Programming", 2)) add_course(students, "Peter", ("Data Structures and Algorithms", 0)) add_course(students, "Peter", ("Introduction to Programming", 2)) print() print(students) print() print_student(students, "Peter")
解决方案
问题1:替换特定课程成绩的思路
元组本身不可变,但外层的列表是可变的。我们可以通过找到对应课程在列表中的索引,用新元组直接替换旧元组,或者先删除旧元组再添加新元组(适用于需要更新的场景)。核心是操作可变的列表容器,而非不可变的元组本身。
问题2:处理重修逻辑的完整实现
修改add_course函数,实现「过滤0分、高分更新、去重」的核心逻辑,同时简化其他函数的冗余代码:
def add_student(students: dict, name: str): # 简化初始化逻辑:直接用空列表标记无课程,避免[()]的混淆 if name not in students: students[name] = [] return students def print_student(students: dict, name: str): if name not in students: print(f"{name}: no such person in the database") elif not students[name]: # 直接判断列表是否为空 print(f"{name}:\n no completed courses") else: print(f"{name}:\n {len(students[name])} completed courses:") for course_name, grade in students[name]: # 元组解包,代码更简洁 print(f" {course_name} {grade}") # 用生成器求和,高效且易读 total_grade = sum(grade for _, grade in students[name]) average = total_grade / len(students[name]) print(f" average grade: {average}") return def add_course(students: dict, name: str, course: tuple): course_name, grade = course # 第一步:直接过滤成绩为0的课程 if grade == 0: return students if name not in students: print(f"{name}: no such person in the database") return students # 第二步:遍历课程列表,检查是否已有该课程 is_updated = False for idx, (existing_course, existing_grade) in enumerate(students[name]): if existing_course == course_name: # 新成绩更高才更新 if grade > existing_grade: students[name][idx] = course # 用新元组替换旧元组 is_updated = True break # 第三步:未找到对应课程则添加新记录 if not is_updated: students[name].append(course) return students if __name__ == "__main__": students = {} add_student(students, "Peter") print() add_course(students, "Peter", ("Introduction to Programming", 3)) add_course(students, "Peter", ("Advanced Course in Programming", 2)) add_course(students, "Peter", ("Data Structures and Algorithms", 0)) add_course(students, "Peter", ("Introduction to Programming", 2)) print() print(students) print() print_student(students, "Peter")
关键修改说明
add_student:用空列表替代[()]作为无课程的标记,逻辑更直观;print_student:使用元组解包和生成器求和,简化代码结构,提升可读性;add_course:- 先过滤成绩为0的课程,直接跳过添加;
- 遍历学生课程列表,找到已有课程则对比成绩,仅在新成绩更高时更新;
- 修复原函数中
course[0] not in students的错误判断(原逻辑完全错误,应该检查课程名是否在学生的课程列表中)。
运行修改后的代码,Peter的课程列表中只会保留Introduction to Programming的3分记录,低分2的重复记录不会被添加,0分课程也会被过滤。
内容的提问来源于stack exchange,提问作者sammur
相关产品推荐
相关产品推荐

