青少年 Python 入门 | 数据思维——打造「个人学习数据仪表盘」适合人群:Python 入门(建议 6~9 年级),学完list和dict后的数据分析项目项目定位:2 课时完整项目(120 分钟),成品是一个交互式学习数据分析工具教学目标:list of dict数据结构、sorted排序、数据聚合统计、控制台可视化、文件持久化、数据思维启蒙目录为什么做「数据仪表盘」第一课时:从一条数据到一张表第二课时:从一张表到一个仪表盘完整代码教学指南拓展方向1. 为什么做「数据仪表盘」编程教育中常被忽略的一件事大多数入门课教的是语法:变量、循环、函数。但编程真正改变世界的方式,是用数据做决策。这节课的目标不是教一个新语法,而是让学生用他们已经会的list、dict、for、if,做一件真正有价值的事情——分析自己的学习数据。项目的真实感这个项目里没有"假设的成绩",学生输入的是他们真实的期末各科分数、每天的学习时长、错题数量。当他们看到程序输出"你的数学比上次进步了 12 分,是进步最大的科目"时,那种反馈是任何玩具项目给不了的。本节课的数据结构整个项目围绕一个核心结构展开:# 一条学习记录{"日期":"2026-06-15","科目":"数学","学习时长":45,# 分钟"做题数量":20,"正确数量":16,"心情":"好"# 好/一般/差}十几条这样的记录组成一个列表。对这个列表做各种操作,就是这节课的全部内容。2. 第一课时:从一条数据到一张表2.1 手动造三条数据——理解结构先不写交互,直接在代码里写死几条数据,让学生"看到"数据结构长什么样:records=[{"日期":"2026-06-15","科目":"数学","学习时长":45,"做题数量":20,"正确数量":16},{"日期":"2026-06-15","科目":"英语","学习时长":30,"做题数量":15,"正确数量":12},{"日期":"2026-06-16","科目":"数学","学习时长":60,"做题数量":25,"正确数量":22}]教学要点:让学生在纸上画出这个结构——几行几列?每一行代表什么?每一列是什么类型?2.2 遍历这张表——回答第一个问题“数学总共学了多久?”total_math_minutes=0math_sessions=0forrinrecords:ifr["科目"]=="数学":total_math_minutes=total_math_minutes+r["学习时长"]math_sessions=math_sessions+1print("数学:共学习 "+str(math_sessions)+" 次")print("总时长:"+str(total_math_minutes)+" 分钟")ifmath_sessions0:print("平均每次:"+str(round(total_math_minutes/math_sessions,1))+" 分钟")这时候学生会发现:写代码和用眼睛看不一样。用眼睛看表需要一行一行扫描,代码一瞬间就算完了。这就是自动化的力量。2.3 计算正确率——引入"派生数据"“数学的正确率是多少?”math_total_questions=0math_correct=0forrinrecords:ifr["科目"]=="数学":math_total_questions=math_total_questions+r["做题数量"]math_correct=math_correct+r["正确数量"]ifmath_total_questions0:accuracy=math_correct/math_total_questions*100print("数学正确率:"+str(round(accuracy,1))+"%")else:print("还没有数学记录。")关键洞察:“正确率"不是我们存在字典里的字段,而是从已有数据计算出来的。这就是"派生数据”——数据思维的第一课。2.4 封装成函数——从"写一遍"到"随时调用"当学生发现"每个科目都要写一遍差不多的代码",就是引入函数的完美时机:defsubject_summary(records,subject_name):"""返回指定科目的学习摘要"""total_time=0total_questions=0total_correct=0session_count=0forrinrecords:ifr["科目"]==subject_name:total_time=total_time+r["学习时长"]total_questions=total_questions+r["做题数量"]total_correct=total_correct+r["正确数量"]session_count=session_count+1ifsession_count==0:returnNone# 没有该科目的记录accuracy=total_correct/total_questions*100\iftotal_questions0else0return{"科目":subject_name,"次数":session_count,"总时长":total_time,"总题数":total_questions,"正确率":round(accuracy,1)}# 使用函数math_info=subject_summary(records,"数学")ifmath_info:print("数学:共 "+str(math_info["次数"])+" 次,"+str(math_info["总时长"])+" 分钟,"+"正确率 "+str(math_info["正确率"])+"%")2.5 手动排序——理解"比较"的本质“哪个科目正确率最高?”不用sorted(),先让学生用手动方式理解排序逻辑:# 先收集所有科目的摘要subjects=["数学","英语","语文","科学"]summaries=[]forsubjinsubjects:info=subject_summary(records,subj)ifinfo:summaries.append(info)# 手动找最高正确率best_subject=Nonebest_accuracy=-1forsinsummaries:ifs["正确率"]best_accuracy:best_accuracy=s["正确率"]best_subject=s["科目"]print("正确率最高的科目:"+best_subject+"("+str(best_accuracy)+"%)")教学要点:让学生用自然语言描述刚才的逻辑——"先假设最高分是-1,然后每看一个科目就问:你比当前最高分高吗?如果是,你就是新的最高分。"这就是遍历求最值的算法思维。2.6 引入sorted()—— 从手动到自动理解手动排序后,sorted()就不再是魔法:# 按正确率从高到低排序summaries_sorted=sorted(summaries,key=lambdas:s["正确率"