Python教程16:数据结构综合实战
Python 教程 16:数据结构综合实战 “纸上得来终觉浅,绝知此事要躬行。” 学习了列表、元组、字典、集合后,让我们通过一个实际项目——学生成绩管理系统,把这些知识串起来,体会如何选择和组合不同的数据结构。 1. 项目需求 开发一个学生成绩管理系统,功能包括: 添加学生信息 录入和修改成绩 查询学生成绩 统计分析(平均分、最高分等) 筛选功能(如成绩优秀的学生) 2. 数据结构设计 方案选择 1# 学生信息:用字典 2student = { 3 "id": "2024001", 4 "name": "张三", 5 "age": 18, 6 "scores": { # 成绩:嵌套字典 7 "数学": 95, 8 "英语": 88, 9 "物理": 92 10 } 11} 12 13# 所有学生:用列表存储 14students = [ 15 {"id": "2024001", "name": "张三", "age": 18, "scores": {"数学": 95}}, 16 {"id": "2024002", "name": "李四", "age": 19, "scores": {"数学": 88}}, 17] 18 19# 学号索引:用字典加速查找 20students_by_id = { 21 "2024001": students[0], 22 "2024002": students[1], 23} 3. 核心功能实现 3.1 学生管理类 1class StudentManager: 2 """学生成绩管理系统""" 3 4 def __init__(self): 5 self.students = {} # {学号: 学生信息} 6 7 def add_student(self, student_id, name, age): 8 """添加学生""" 9 if student_id in self.students: 10 print(f"学号{student_id}已存在") 11 return False 12 13 self.students[student_id] = { 14 "id": student_id, 15 "name": name, 16 "age": age, 17 "scores": {} 18 } 19 print(f"✓ 添加学生:{name}") 20 return True 21 22 def add_score(self, student_id, subject, score): 23 """添加成绩""" 24 if student_id not in self.students: 25 print(f"学号{student_id}不存在") 26 return False 27 28 self.students[student_id]["scores"][subject] = score 29 print(f"✓ 录入成绩:{subject} = {score}") 30 return True 31 32 def get_student(self, student_id): 33 """查询学生信息""" 34 return self.students.get(student_id) 35 36 def get_average(self, student_id): 37 """计算学生平均分""" 38 student = self.get_student(student_id) 39 if not student or not student["scores"]: 40 return None 41 42 scores = student["scores"].values() 43 return sum(scores) / len(scores) 44 45 def get_top_students(self, n=5): 46 """获取成绩最好的N名学生""" 47 # 计算每个学生的平均分 48 student_avgs = [] 49 for sid, student in self.students.items(): 50 if student["scores"]: 51 avg = sum(student["scores"].values()) / len(student["scores"]) 52 student_avgs.append((student["name"], avg)) 53 54 # 排序并返回前N名 55 student_avgs.sort(key=lambda x: x[1], reverse=True) 56 return student_avgs[:n] 57 58 def get_subject_stats(self, subject): 59 """统计某科目的成绩分布""" 60 scores = [] 61 for student in self.students.values(): 62 if subject in student["scores"]: 63 scores.append(student["scores"][subject]) 64 65 if not scores: 66 return None 67 68 return { 69 "count": len(scores), 70 "max": max(scores), 71 "min": min(scores), 72 "avg": sum(scores) / len(scores) 73 } 74 75 def find_by_score_range(self, subject, min_score, max_score): 76 """查找某科目分数在指定范围内的学生""" 77 result = [] 78 for student in self.students.values(): 79 if subject in student["scores"]: 80 score = student["scores"][subject] 81 if min_score <= score <= max_score: 82 result.append({ 83 "name": student["name"], 84 "score": score 85 }) 86 return result 3.2 使用示例 1# 创建管理器 2manager = StudentManager() 3 4# 添加学生 5manager.add_student("2024001", "张三", 18) 6manager.add_student("2024002", "李四", 19) 7manager.add_student("2024003", "王五", 18) 8 9# 录入成绩 10manager.add_score("2024001", "数学", 95) 11manager.add_score("2024001", "英语", 88) 12manager.add_score("2024001", "物理", 92) 13 14manager.add_score("2024002", "数学", 87) 15manager.add_score("2024002", "英语", 94) 16manager.add_score("2024002", "物理", 89) 17 18manager.add_score("2024003", "数学", 92) 19manager.add_score("2024003", "英语", 85) 20manager.add_score("2024003", "物理", 95) 21 22# 查询学生 23student = manager.get_student("2024001") 24print(f"\n学生信息:{student['name']}") 25print(f"成绩:{student['scores']}") 26 27# 计算平均分 28avg = manager.get_average("2024001") 29print(f"平均分:{avg:.2f}") 30 31# 获取前3名 32print("\n前3名学生:") 33top_students = manager.get_top_students(3) 34for i, (name, avg) in enumerate(top_students, 1): 35 print(f"{i}. {name}: {avg:.2f}") 36 37# 统计数学成绩 38print("\n数学成绩统计:") 39stats = manager.get_subject_stats("数学") 40print(f"人数:{stats['count']}") 41print(f"最高分:{stats['max']}") 42print(f"最低分:{stats['min']}") 43print(f"平均分:{stats['avg']:.2f}") 44 45# 查找数学成绩90分以上的学生 46print("\n数学90分以上:") 47excellent = manager.find_by_score_range("数学", 90, 100) 48for item in excellent: 49 print(f"{item['name']}: {item['score']}") 4. 数据结构选择分析 为什么用字典存储学生 1# 方案1:列表(不推荐) 2students_list = [...] 3# 查找学生需要遍历:O(n) 4 5# 方案2:字典(推荐) 6students_dict = {"2024001": {...}} 7# 查找学生直接访问:O(1) 选择依据:需要频繁通过学号查找学生,字典更高效。 ...