Python字典进阶:从‘学生成绩统计’到‘自动选课分析’,教你写出更地道的代码
Python字典进阶从‘学生成绩统计’到‘自动选课分析’教你写出更地道的代码在Python的世界里字典dict就像是一个神奇的魔法口袋它能以键值对的形式存储各种数据让信息的存取变得异常高效。但很多初学者往往只停留在能用的层面却忽略了字典真正的威力。本文将带你从学生成绩统计、选课分析等实际场景出发对比能用和好用的代码区别让你的Python代码更加地道、高效。1. 字典基础操作的进阶写法1.1 安全访问get() vs 直接访问新手常犯的错误是直接通过dict[key]访问不存在的键导致程序抛出KeyError。来看一个学生成绩查询的例子# 新手写法危险 student_scores {Alice: 90, Bob: 85} print(student_scores[Charlie]) # KeyError! # 高手写法安全 print(student_scores.get(Charlie, 未找到该学生)) # 输出未找到该学生get()方法的第二个参数可以指定默认值这在处理可能缺失的数据时特别有用。比如统计学生成绩时# 统计分数段人数 scores [85, 92, 78, 85, 90, 78, 92, 85] score_counts {} for score in scores: score_counts[score] score_counts.get(score, 0) 1 print(score_counts) # {85: 3, 92: 2, 78: 2, 90: 1}1.2 字典合并的艺术合并两个字典时新手可能会用循环逐个添加而高手则会用更优雅的方式# 两个班级的学生成绩 class1 {Alice: 90, Bob: 85} class2 {Charlie: 88, David: 92} # 新手写法 merged class1.copy() for k, v in class2.items(): merged[k] v # 高手写法1 merged {**class1, **class2} # 高手写法2Python 3.9 merged class1 | class22. 字典推导式简洁高效的创建方式字典推导式是Python中非常强大的特性能让代码既简洁又高效。来看一个学生信息处理的例子students [ {name: Alice, age: 20, score: 90}, {name: Bob, age: 21, score: 85}, {name: Charlie, age: 19, score: 92} ] # 创建姓名到分数的映射 # 新手写法 name_to_score {} for student in students: name_to_score[student[name]] student[score] # 高手写法 name_to_score {student[name]: student[score] for student in students}更复杂的例子筛选出成绩大于90的学生top_students {s[name]: s[score] for s in students if s[score] 90}3. collections模块中的字典工具Python的collections模块提供了几种特殊的字典类型能解决很多实际问题。3.1 defaultdict处理缺失键的优雅方案统计学生选课情况时使用defaultdict可以让代码更简洁from collections import defaultdict # 学生选课数据 student_courses [ (Alice, Math), (Bob, Physics), (Alice, Chemistry), (Charlie, Math), (Alice, Physics) ] # 统计每个学生的选课数量 course_counts defaultdict(int) for student, course in student_courses: course_counts[student] 1 print(dict(course_counts)) # {Alice: 3, Bob: 1, Charlie: 1}3.2 Counter专业的计数器统计学生成绩分布时Counter是绝佳选择from collections import Counter scores [85, 92, 78, 85, 90, 78, 92, 85] score_counter Counter(scores) print(score_counter) # Counter({85: 3, 92: 2, 78: 2, 90: 1}) print(score_counter.most_common(2)) # [(85, 3), (92, 2)]4. 复杂数据处理学生选课系统实战让我们用一个完整的选课系统例子来综合运用这些技巧。4.1 数据准备# 学生数据 students { S001: {name: Alice, grade: A}, S002: {name: Bob, grade: B}, S003: {name: Charlie, grade: A}, S004: {name: David, grade: C} } # 课程数据 courses { C101: {name: Math, capacity: 2}, C102: {name: Physics, capacity: 3}, C103: {name: Chemistry, capacity: 2} } # 选课记录 (学生ID: [课程ID列表]) enrollments { S001: [C101, C102], S002: [C101], S003: [C102, C103], S004: [] }4.2 统计每门课程的选课人数from collections import defaultdict course_counts defaultdict(int) for courses_list in enrollments.values(): for course_id in courses_list: course_counts[course_id] 1 print(dict(course_counts)) # {C101: 2, C102: 2, C103: 1}4.3 找出选课冲突的学生# 假设课程时间冲突信息 schedule { C101: Mon 9:00, C102: Mon 9:00, # 与C101时间冲突 C103: Tue 10:00 } # 找出有时间冲突的学生 conflicts defaultdict(list) for student_id, courses_list in enrollments.items(): # 收集学生所选课程的时间 times [schedule[course_id] for course_id in courses_list if course_id in schedule] # 如果有重复时间说明有冲突 if len(times) ! len(set(times)): conflicts[student_id] courses_list print(dict(conflicts)) # {S001: [C101, C102], S003: [C102, C103]}4.4 按成绩分组学生from collections import defaultdict grade_groups defaultdict(list) for student_id, info in students.items(): grade_groups[info[grade]].append(student_id) print(dict(grade_groups)) # {A: [S001, S003], B: [S002], C: [S004]}5. 性能优化避免字典使用的常见陷阱5.1 键的存在性检查检查键是否存在时新手可能会这样写if key in my_dict.keys(): # 不必要的调用keys() ...更高效的写法if key in my_dict: # 直接检查字典 ...5.2 字典视图的高效利用Python 3中的keys(), values(), items()返回的是视图对象它们比Python 2中的列表更高效# 高效遍历 for key, value in student_dict.items(): ...5.3 避免频繁的字典更新当需要批量更新字典时使用update()比逐个赋值更高效# 低效 for k, v in new_items.items(): my_dict[k] v # 高效 my_dict.update(new_items)6. 高级技巧字典的排序与自定义操作6.1 按值排序对学生成绩字典按分数排序student_scores {Alice: 90, Bob: 85, Charlie: 92} # 按分数降序排序 sorted_scores sorted(student_scores.items(), keylambda item: item[1], reverseTrue) print(sorted_scores) # [(Charlie, 92), (Alice, 90), (Bob, 85)]6.2 使用operator模块对于更复杂的排序可以使用operator模块from operator import itemgetter students [ {name: Alice, score: 90, age: 20}, {name: Bob, score: 85, age: 21}, {name: Charlie, score: 92, age: 19} ] # 按分数降序年龄升序排序 students.sort(keyitemgetter(score, age), reverseTrue)7. 实际案例自动选课分析系统让我们构建一个完整的选课分析系统展示字典在实际项目中的应用。7.1 数据加载与预处理import json from collections import defaultdict # 假设从JSON文件加载数据 def load_data(file_path): with open(file_path) as f: return json.load(f) # 加载数据 students load_data(students.json) courses load_data(courses.json) enrollments load_data(enrollments.json) # 预处理建立课程到学生的反向映射 course_to_students defaultdict(list) for student_id, course_list in enrollments.items(): for course_id in course_list: course_to_students[course_id].append(student_id)7.2 热门课程分析# 找出选课人数最多的3门课程 popular_courses sorted(course_to_students.items(), keylambda item: len(item[1]), reverseTrue)[:3] print(最受欢迎的课程) for course_id, student_ids in popular_courses: print(f{courses[course_id][name]}: {len(student_ids)}人)7.3 学生选课模式分析# 分析学生的选课数量分布 num_courses_dist defaultdict(int) for student_id in enrollments: num_courses len(enrollments[student_id]) num_courses_dist[num_courses] 1 print(学生选课数量分布) for num, count in sorted(num_courses_dist.items()): print(f选{num}门课的学生: {count}人)7.4 推荐系统雏形# 简单的课程推荐基于同年级学生的选课 def recommend_courses(student_id, n3): grade students[student_id][grade] same_grade_students [s_id for s_id, info in students.items() if info[grade] grade and s_id ! student_id] # 统计同年级学生常选的课程 course_scores defaultdict(int) for s_id in same_grade_students: for course_id in enrollments.get(s_id, []): course_scores[course_id] 1 # 排除已选课程 taken_courses set(enrollments.get(student_id, [])) recommendations [course_id for course_id in course_scores if course_id not in taken_courses] # 按受欢迎程度排序 recommendations.sort(keylambda c: course_scores[c], reverseTrue) return recommendations[:n]
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2508159.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!