
如果你正在跟“Python第二次作业”较劲那我要先恭喜你你已经跨过了从“照着教程抄代码”到“自己动手拼逻辑”的那道坎。第一次作业大家都差不多无非是打印个Hello World、算个两数之和、写个简单的判断第二次作业就开始见真章了——题目开始要求你处理流程、组织数据、封装函数甚至还得跟文件打交道。很多人在这一步突然卡住不是语法没学会而是不知道一道题到底该怎么拆代码该怎么组织报错该怎么查。这篇文章我会把一份典型的Python第二次作业拆开揉碎从作业背后的能力模型、环境准备、核心知识点、完整实操案例到高频报错排查再到作业后怎么继续往前走一条线讲清楚。不管你是正在自学、跟着网课做作业还是在补交一份迟来的作业这篇文章都能让你少走不少弯路。我尽量不讲废话每一条都是实操中验证过的经验。1. 第二次作业到底在练什么先读懂题目背后的能力模型1.1 从“照葫芦画瓢”到“自己搭积木”的转折点第一次作业练的是“认识语法”知道print能输出知道变量能存东西知道if能判断。这些知识点是零散的就像你刚认识了一堆积木块但还没开始拼。第二次作业的定位就开始变了——它逼着你把积木拼成一个小结构。我见过不少学生的第二次作业题目五花八门打印九九乘法表、判断闰年、模拟猜数字、统计一段文字里某个字符出现的次数、用循环画一个菱形图案……看起来是不同题目但本质上是同一组能力顺序执行一句一句往下走这是程序的地基。分支判断不同条件走不同路径if/elif/else的运用。循环控制重复执行一段逻辑for和while的选择break和continue的时机。数据的收集与处理把数据存到列表中遍历、统计、筛选。抽象与复用把一段重复出现的逻辑抽成函数用参数控制不同输入。这些能力点单独拿出来都不难但组合在一道综合题里人的大脑就容易“过载”。你不再是“我知道这个语法”而要“在合适的时机用合适的语法”。这就是很多人第二次作业做得费劲的真正原因——不是不会语法是不会“组装”。那怎么破我的建议是拿到题目先别写代码先在纸上把流程画出来。这道题输入什么、输出什么中间要几步哪几步是重复的哪几步是要判断的把这些问题想清楚再动手代码往往水到渠成。这个习惯你从第二次作业开始建立后面学到爬虫、数据分析、自动化脚本时会感激现在的自己。1.2 一份“合格”的Python作业验收标准其实不止“能跑”很多初学者的心态是代码跑通了作业就完事了。但如果你把标准定得高一点会发现作业其实分好几个层次。最低层次是“能跑”输入样例能正确输出不报错。这个没问题但只是及格线。再往上一层是“健壮”用户输入了不合法数据程序不会崩溃而是给一句提示文件不存在时不会直接抛异常而是有相应的处理。再往上一层是“可读”变量命名有意义不叫a、b、c而叫num、total、scores函数拆得合理一个函数只干一件事关键地方有注释别人包括一个月后的你能看懂。我为什么强调这件事因为我见过太多作业代码能跑但变量全是x、y、z逻辑全挤在main里缩进乱七八糟连作者本人都解释不清自己写了什么。这种代码在第二次作业里还能混过去等你开始写爬虫、写数据处理脚本代码一长就崩盘——你根本没法调试。所以我建议你在写第二次作业时就强制自己养成三个习惯第一变量名用完整的英文单词或缩写不要用单个字母。比如total_price而不是tpuser_input而不是ui。第二每个函数上方写一行注释说明这个函数干什么、参数是什么、返回什么。第三写完作业后自言自语一遍如果我是别人我能看懂这段代码吗看不懂就重构。这些习惯比作业本身的分数重要得多。算法题做不出来可以学代码烂成稀泥就只能推倒重来。2. 作业前的环境准备少走弯路才是真的快2.1 Python解释器与编辑器别在一开始就选错组合写作业的第一步不是写代码而是把环境准备好。别小看这一步我亲眼见过有人花了一下午在装环境上最后发现是Python版本和代码不兼容。先说Python版本。目前主流版本是Python 3.8及以上的3.x系列像Python 3.10、3.11、3.12都很常见。如果是做第二次作业直接装最新稳定版就行不用纠结。到官网下载安装包时有一个一定要做的动作在安装向导的第一个页面上勾选“Add Python to PATH”。很多人装完Python后在命令行里输入python提示“不是内部或外部命令”十有八九就是漏了这个勾选。如果你已经装完才发现没勾也不用重装手动把Python的安装目录和Scripts目录加到系统环境变量Path里即可。具体路径一般是C:\Users\你的用户名\AppData\Local\Programs\Python\Python3xx 和同目录下的Scripts文件夹。编辑器我推荐VSCode免费、插件生态好、调试功能对新手很友好。装完VSCode后再装一个官方Python插件扩展商店搜Python认准微软发布的那个就能获得语法高亮、代码补全、点击运行、断点调试等功能。建一个以.py结尾的文件写代码、右键运行或者点右上角的三角形按钮是日常最顺手的操作。还有一个新手容易踩的坑python和cmd的关系。你打开Windows的命令行或者PowerShell输入python会进入一个交互式命令行显示提示符在那里可以直接写一行执行一行。这叫交互模式适合快速验证语法不适合写完整作业。真正的作业要写成.py文件用解释器运行整个文件。很多人在交互模式里写了一段完整程序一按回车就报错——因为回车代表“这句话结束了”而完整程序根本不是一个表达式。记住日常验证用交互模式写作业用脚本文件。2.2 第二次作业需不需要第三方库标准答案大多数时候是“不需要”第二次作业的范围一般不会超过标准库内置函数、内置类型、random、math、sys这些直接import就能用不需要额外安装。所以如果你的作业只是判断、循环、列表、字符串、文件读写那环境只需要Python本身不需要装任何第三方库。但如果你的作业开始涉及矩阵、可视化比如要求构建邻接矩阵、画统计图那就需要用到numpy和matplotlib了。这两个库的安装非常简单打开命令行执行pip install numpy和pip install matplotlib就行。如果下载速度慢可以换用国内镜像源比如在pip install后面加一个 -i https://pypi.tuna.tsinghua.edu.cn/simple 参数。装完之后在Python文件里import numpy不报错就说明成功。还有同学问到cv2OpenCV这是计算机视觉方向的内容了第二次作业基本不会用到。如果只是为了交作业不要因为看到网络教程里各种炫酷的代码就乱装一堆库装错了或者版本冲突还得折腾半天反而耽误正事。先看清作业要求用到什么装什么这是最朴素的真理。3. 作业中的核心知识点逐个击破理论、代码与避坑一起讲3.1 变量与数据类型先搞清楚“盒子”和“盒子里的东西”Python的变量不需要声明类型直接把一个值赋给变量就行。这个设计非常方便但也带来了一些让人迷惑的地方变量本身不是一个“容器”而更像一个“标签”贴在某个值上。你执行a 1时是把标签a贴在整数1上再执行a hello是把a撕下来贴到字符串“hello”上。整型和字符串是可以互相“换贴”的这在Python里完全合法。不过语言合法不代表你的逻辑没问题。第二次作业里最常见的报错之一就是int和str混用。比如用户输入一个数字你用input()接收得到的是字符串然后直接拿它做数学运算就会报TypeError: unsupported operand type(s) for : int and str。这个报错的意思是加号两边一个整数一个字符串Python不知道该怎么加。解决方案就是用int()或float()把input()的结果转换一下。除了int、float、str、bool四种基本类型第二次作业里还会大量用到list列表它是一种有序、可变的序列用方括号表示。列表支持索引、切片、遍历、追加、删除等操作。你看到的“Python数组切片命令”相关热词其实说的就是列表切片scores[1:5]表示取从索引1到索引4的元素切片是左闭右开区间很多人在这里被绕晕需要反复记。顺便说一个检查类型的常用方法用type()函数。写代码时拿不准某个变量的类型就在中间加一行print(type(var))输出会告诉你这是class int还是class str。这个习惯能在调试时帮你省下大量时间。3.2 分支与循环控制程序的“方向盘”分支结构if/elif/else是程序“选择路径”的方式。新手容易忽略两点第一判断条件要写对Python里用判断相等是赋值写错的话要么逻辑出错要么直接SyntaxError第二条件之间的逻辑要用对和与或分别是and和or而不是Java里的和||。比如要判断一个年份是闰年条件是“能被4整除但不能被100整除或者能被400整除”对应的代码是if (year % 4 0 and year % 100 ! 0) or (year % 400 0): print(闰年)注意运算符优先级and比or更高所以不加括号时“and先结合”。我建议新手写复杂条件时干脆都加上括号清晰明了不会出歧义。循环结构有for和while两种。for循环适合遍历一个已知范围或序列比如for i in range(10)表示循环10次i从0到9。range()有三种用法range(10)是0到9range(3, 10)是3到9range(3, 10, 2)是3、5、7、9步长为2。while循环适合不知循环次数、只知道循环条件的场景比如猜数字游戏里“直到猜对为止”。不过在第二次作业阶段绝大多数题目都能用for解决优先for。最折磨初学者的其实是缩进。Python用缩进来表示代码块的层次关系这和其他语言用大括号不一样。同样一段代码缩进不同逻辑就可能完全不同。我见过有人写循环体忘记缩进结果循环只执行了最后一行的内容。排查方法很简单看每一行代码的缩进层级是不是符合逻辑循环里的代码必须比for那一行多一层缩进。break和continue也经常让人犯糊涂。break是提前结束整个循环continue是跳过当前这一次循环直接进入下一次。就像在队伍里排队break是“我不排了直接离开”continue是“这次轮到我但我跳过继续等下一个人”。第二次作业里很多题需要你用break来退出循环比如猜数字猜对了就退出。3.3 函数把逻辑装进“工具箱”函数是第二次作业里最值得花心思掌握的知识点。它的核心作用有两个复用和抽象。复用是同一段逻辑不用写两遍抽象是把复杂的任务拆成小块每个小块用一个函数表示主程序像搭积木一样把它们组合起来。定义函数用def关键字后面跟函数名、括号里的参数、冒号函数体缩进。函数可以return一个值也可以不return而只执行操作。一个常见的坑是函数内部定义的变量是局部变量函数外面访问不到。这就像工具箱里的工具只能在工具箱所在小屋里使用拿到外面就不好使了。如果需要函数内部的结果就必须通过return把它传出来然后在调用函数的地方用一个变量接住。函数参数还可以设置默认值比如def greet(nameworld):这样调用greet()和greet(Python)都会有效果。另一个比较实用的知识点是参数顺序带默认值的参数必须放在不带默认值参数的后面否则会报SyntaxError。在第二次作业阶段一个功能不一定非要拆成函数但如果你发现某段逻辑出现了三次以上或者一个主程序写了太长、自己都看晕了那就是该拆分的时候了。你不需要一开始就抽象得很漂亮先写出能跑的程序再重构会比一上来就想完美方案简单得多。先跑通再优化永远是最安全的学习路径。4. 实操全流程用两道经典题把完整作业跑通4.1 综合题一李白打酒——一道经典的逆向思维题热词里看到了李白打酒这道题是我见过很经典的一道Python作业题非常推荐用来练习循环和逻辑。题目是这样的李白街上走提壶去买酒。遇店加一倍见花喝一斗。三遇店和花喝光壶中酒。试问壶中原有多少酒解释一下李白提着酒壶出门遇到酒店壶中酒量翻倍遇到花丛喝掉一斗。他在路上共三次遇到店三次遇到花顺序不一定是店店店花花花可能是交错出现最后壶中酒正好喝光。问初始壶中有多少酒。这道题有两个思路都很值得掌握。思路一是正向枚举。设初始酒量为x店的操作为乘以2花的操作为减去1。三次店和三次花的顺序未知所有可能的顺序组合用“店”和“花”的排列表示。但更简单的做法是直接把“三遇店和花”理解为一个固定顺序实际上常见的解法是遍历所有可能的顺序序列比如店、店、花、店、花、花每种顺序算一遍初始值。如果题目没给顺序就穷举所有6种顺序3个店和3个花的排列判断什么顺序下正推结果为0。思路二更简洁——逆向推导。从最后“喝光”开始倒推最后一次操作是见花喝一斗那最后一次操作前壶里有1斗以此为起点往前一步步还原。遇到“花”的逆操作是“加上一斗”遇到“店”的逆操作是“减少一半”。只要知道店和花出现的顺序就能逆推出初始值。如果题目里店和花的顺序未知正确答案往往不止一种。下面给出一段完整的正向枚举代码穷举所有“店与花”的排列组合import itertools # 用 1 代表遇店翻倍用 0 代表遇花喝一斗 actions_pool [1, 1, 1, 0, 0, 0] # 题目背景设定每次遇店翻倍每次遇花喝一斗 def check_order(order): # 未知初始酒量这里反过来从最后的 0 倒推 # 倒推时遇店1的逆操作是减半遇花0的逆操作是加一 wine 0 for action in reversed(order): if action 1: # 遇店正推翻倍所以倒推减半 wine wine / 2 else: # 遇花正推减一所以倒推加一 wine wine 1 return wine # 用 set 去掉重复的排列 unique_orders set(itertools.permutations(actions_pool)) for order in unique_orders: initial check_order(order) # 酒量通常以“斗”为单位合理结果一般是有限小数/整数 if abs(initial - round(initial)) 1e-9: print(order, - 初始酒量:, int(round(initial)))这道题练的不只是循环和判断更重要的是一种“变换视角”的思维既然正推不好求就试着从结果反推。这种逆向思维在后面的算法学习中会不断出现值得在第二次作业阶段就埋下种子。4.2 综合题二文本统计并输出报告——把文件操作、字符串和字典串起来再来讲一道非常接地气的综合题给一个文本文件统计里面有多少字符、多少行、多少个单词并找出出现频率最高的几个单词。这道题和很多实际场景是相通的也是后续文本处理、数据分析的基础。这道题我建议分四步走第一步读文件。用open(text.txt, r, encodingutf-8)打开文件不要忘了编码参数Windows系统下默认编码可能是gbk读UTF-8文件会乱码或者报错。用with open(...) as f的形式Python会自动帮你关闭文件不用手动close。第二步按行处理。for line in f遍历文件的每一行。统计行数很简单每读一行就计数加1。字符数可以用len(line)累加但要注意换行符也算一个字符实际需求中可能需要strip()去掉首尾空白。第三步拆分单词。把每一行按空格或标点拆分成单词可以用line.split()它会把连续空白字符当成一个分隔符处理。标点符号会成为单词的一部分比如“hello,”会被当成一个单词这通常是可接受的简化。如果要处理干净一点可以用正则表达式提取字母比如re.findall(r[a-zA-Z], line)正则可能看起来复杂但理解了就会觉得很强大。第四步词频统计。用字典键是单词值是出现次数。遍历单词列表如果单词已经在字典里就加1否则就初始化为1。最后按出现次数排序用sorted(word_count.items(), keylambda item: item[1], reverseTrue)取前N个。完整代码我给一个精炼版本import re def read_and_count(file_path): line_count 0 char_count 0 word_count {} with open(file_path, r, encodingutf-8) as f: for line in f: line_count 1 char_count len(line.strip()) words re.findall(r[a-zA-Z0-9], line.lower()) for word in words: word_count[word] word_count.get(word, 0) 1 return line_count, char_count, word_count file_path text.txt lines, chars, word_counter read_and_count(file_path) print(f共 {lines} 行{chars} 个字符不含换行) print(f出现次数最多的前 10 个单词) top_words sorted(word_counter.items(), keylambda x: x[1], reverseTrue)[:10] for word, cnt in top_words: print(f{word}: {cnt}) # 将报告写入文件避免控制台乱码或内容太多刷屏 with open(report.txt, w, encodingutf-8) as out: out.write(f行数: {lines}\n) out.write(f字符数: {chars}\n) out.write(Top10:\n) for word, cnt in top_words: out.write(f{word}: {cnt}\n)这道题的精华点在于它把字符串处理、正则、字典、排序、文件读写全部串在一起正好覆盖第二次作业的核心知识面。把这道题啃下来作业里的绝大部分综合题都有思路了。延伸一步如果你想把统计结果画成柱状图可以装matplotlib把Top10单词的频次画出来。画图时经常碰到的问题就是“横坐标太密集”解决办法是调整figure大小、旋转标签角度比如fig.autofmt_xdate()或者plt.xticks(rotation45)再加plt.tight_layout()保证标签不被裁剪掉。愿意做这一步的同学你的第二次作业已经超出平均水平了。4.3 邻接矩阵与矩阵操作为数据结构和算法打基础如果第二次作业里出现了“构建邻接矩阵”或“矩阵0”这类题目说明老师已经在前瞻性地为图论和算法做铺垫了。邻接矩阵听起来高端其实就是用一个二维列表表示图中结点之间的连接关系matrix[i][j]等于1表示结点i和结点j有边相连等于0表示没有。构建一个n行n列的零矩阵在Python里最自然的写法是n 5 # 结点数 matrix [[0] * n for _ in range(n)] # 假设有一条从1到3的边下标从0开始 matrix[1][3] 1新手最容易犯的错误是matrix [[0] * n] * n以为创建了n行实际上这只是创建了同一个行的n个引用改一行其他行全跟着变。这是Python列表机制里的经典陷阱务必记住创建二维列表用列表推导式不要用乘法复制行。与矩阵相关的作业题还有求矩阵的转置、找出矩阵中为0的元素个数、筛选出所有相同的行等等。这些题目都在训练你对“数据如何在二维结构中被索引和遍历”的理解这是理解数组、图像、表格数据的入口。比如图像处理里那个cv2库图像在内存中就是一个多维数组你处理像素本质上就是在操作矩阵的数值。所以别把邻接矩阵当成一个孤立的题目它是在给你后面所有“二维数据”相关技术打地基。5. 高频报错与调试实录我把别人踩过的坑都整理了一遍5.1 新手报错TOP6速查表Python的报错信息已经算非常友好的了它会告诉你错误类型和出错位置。但新手还是容易在看到红色报错时头脑空白。下面这六类报错占据了第二次作业调试场景的绝大部分我做成了一张速查表报错常见原因解决思路SyntaxError语法错误括号没闭合、冒号缺失、字符串引号不成对看报错位置对应的那一行往前多看一行Python经常在报错行前一行就已经出问题了IndentationError缩进不正确该缩进的没缩进或不一致地混用了空格和Tab统一用4个空格缩进VSCode里可以设置“render whitespace”显示空格符NameError变量名或函数名不存在可能拼写错误或未定义就先使用检查变量名拼写确认赋值语句在调用语句之前执行过TypeError类型不匹配比如int和str相加、函数参数类型不对用print(type(var))打印变量类型检查是否需要int()、float()、str()转换IndexError索引越界访问了列表中不存在的下标检查索引是否超出0到len(list)-1的范围尤其注意循环边界AttributeError对象没有某个属性或方法比如对字符串用了append()、对列表用了.lower()先确认对象的类型再确认该类型支持哪些方法dir(对象)可以查看可用方法我自己的习惯是报错后先看最后一行读清楚是什么类型的错再往上翻两行看是哪一行代码触发然后在出错行前后加print把关键变量的值打印出来对比预期结果。90%的新手报错都能靠这招解决。5.2 调试三板斧print、注释法和异常捕获第一板斧是print。最简单也最有效。在程序的各个关键位置打印中间结果——循环的每一次迭代、函数的入口和出口、变量的当前值——让你看到程序实际执行到哪一步、数据变成了什么样。打多了之后问题自然就浮出水面。第二板斧是注释法。当你怀疑某段代码导致整个程序崩溃或输出错误时把这段代码一段一段注释掉看注释掉哪一段后程序行为恢复正常问题就定位在那一段了。这方法听起来笨但在没有调试器的时候能高效缩小问题范围。第三板斧是异常捕获。虽然第二次作业阶段input()基本不会出格但涉及到文件读写和类型转换时健壮性很重要。用try/except包住可能出现异常的代码块try: num int(input(请输入数字: )) except ValueError: print(输入的不是有效数字请重新运行)这里的ValueError表示int()转换失败。异常捕获不会让程序“更好”但至少不会在用户输入非法数据时崩溃出一大片红色报错。对“健壮”有要求的作业这一步很加分。调试时可以配合VSCode的断点功能在行号左侧点击一下出现红点就是断点然后按F5启动调试模式程序会停在断点处你可以在左侧变量窗口查看所有变量的值逐行按F10单步执行。这个能力不是第二次作业的必考项但掌握了你以后写任何Python代码都会速度飞快。5.3 提交作业前的自查清单最后分享一份我自己提交代码前会过一遍的自查清单虽然简单但确实能救回不少没必要的扣分代码能否在别人电脑上直接运行有没有依赖我没说明的外部文件比如需要读取某个txt所有文件路径是否写成了绝对路径建议写成相对路径比如open(data.txt, r)否则换台电脑就报错。input()提示信息是否清晰用户知道要输入什么吗输出格式是否符合题目要求有没有多打了空格、换行或者输出多余的内容变量命名和注释是否到位如果代码是在线判题系统要求的注意不要有多余的调试print输出很多评测系统只认标准输出的精确格式。6. 作业之外第二次作业攒下的能力够你走到多远6.1 从作业到小项目的三个方向第二次作业做完你手里其实已经握着一套非常基础的能力工具箱变量与类型、分支循环、函数、列表、字符串处理、文件读写。这些基础能力组合起来已经够你撬动不少真实方向了爬虫方向。你用requests库下载网页内容用正则表达式或BeautifulSoup提取信息本质上就是在做字符串处理加循环遍历。第二次作业里学的re.findall、列表、字典在爬虫里全都会再次用到。区别只是数据从本地文本变成了网络文本。数据处理方向。你学会的列表、字典和矩阵操作是numpy和pandas的前置直觉。pandas里的DataFrame本质上就是一张有表头的二维表格你可以把它理解为“高级版邻接矩阵”。你在第二次作业里建立起的行列索引概念学数据分析时会非常顺。自动化脚本方向。文件读写加函数封装已经足够写一个批量处理脚本比如把一堆txt文件合并、批量重命名文件、定时备份某个文件夹。这些脚本未必华丽但非常实用能让你成为同学眼中的“技术流”。这些方向都不是一蹴而就的但它们的共同点是都建立在第二次作业的知识地基上。地基稳不稳决定了你楼能盖多高。6.2 看源码的正确姿势不要抄要拆很多同学会遇到“代码不会写干脆找一份Python源码大全参考参考”。我不反对看别人的代码这也是很好的学习方式但要注意姿势。错误的姿势是找到源码复制粘贴改改变量名交上去。这除了应付作业什么也学不到。正确的姿势是这样拿到一份代码先在脑子里或者注释里写下你理解的“程序流程”然后运行它接着改动其中的一个参数、一个条件、一个循环范围观察输出有什么变化再试着删掉某个函数看程序会不会崩、在哪崩最后合上源码凭记忆自己重写一遍。重写不出来也没关系对比着看自己卡在哪一步那一步就是你理解最薄弱的地方正是需要重点补的内容。第二次作业自己去“拆代码”的那股认真劲会让你在阅读源码、调试Bug、解决问题上的能力增长很快。代码能力本质上就是“读代码”和“写代码”的循环你读得懂什么样的代码才写得出什么样的代码。从我自己批改作业的经验来看能在这个阶段把代码写得结构清晰、注释到位的人后续学爬虫、数据分析都会比其他人顺滑很多。反而是那些每次都靠复制粘贴蒙混过去的同学到了第三个、第四个作业就开始原形毕露到处报错却不知道从何查起。第二次作业是一道分水岭能不能把这段路走扎实直接影响你接下来能不能真正把Python用起来。最后分享一个小技巧做完这次作业后把你写的代码再存一份到“练习存档”文件夹里以后每学一个新知识就回来把这份旧作业用新知识重写一遍。比如学了文件读写后把猜数字改成读配置文件再开局学了异常处理后给计算器加上输入合法性判断。你不需要去刷很多题反复重构自己写过的作业就是性价比最高的练习方式。