Python字典进阶:从‘学生成绩统计’到‘自动选课分析’,教你写出更地道的代码

news2026/4/12 2:23:06
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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…