简介《Python100道经典练习题建议收藏》是一份面向Python初学者与进阶者的习题集PDF文档覆盖循环与条件判断、函数与模块、递归、字符串操作、面向对象、矩阵运算、算法、文件操作、日期时间等核心知识点。文档包含100个由易到难的实例从数字组合、个税计算、斐波那契数列等基础题到矩阵相加、杨辉三角、类作用域、磁盘读写等综合练习每题均附有题目描述、程序分析及代码实现部分题目还提供itertools、递归等不同解法。资源共1个PDF文件大小139KB体积小巧、便于离线查阅适合按顺序刷题巩固语法、提升编程思维也可作为教学配套练习素材。已有1466人学习该资源。1. 为什么Python学到半途要回头刷这100道题很多自学Python的人会卡在同一个地方视频教程看完了语法点都知道真让自己写一个统计词频的小脚本却要盯着屏幕半小时。这不是智商问题而是“知道”和“会写”之间缺了一层练习。Python100道经典练习题补的就是这层练习——它不是算法竞赛里那种偏题怪题而是把字符串处理、列表字典、循环函数、文件操作、面向对象这些日常开发最重要的知识点拆成一道道能动手写的小题目。它适合三类人刚学完一套教程但写不出独立代码的新手准备笔试想快速摸底的人以及工作一阵子想检验基本功的开发者。建议收藏的意思是别让它在网盘里吃灰而是把它当成一份可以反复刷的查漏清单。刷题的价值从来不在“做过”而在“做过之后能独立写出来”——这份题集恰好提供了这样一个低门槛、高覆盖的练习场。2. 先看清这100道题题型构成与难度分布拿到任何一份题集别急着从第一题开刷。先花半小时把目录和题型分布过一遍心里有数再动手效率差别很大。这类经典100题有一个共性题目不是随机堆的而是按知识点模块递进编排难度和日常开发的使用频率成正比。下面这张表是我在过这类题集时习惯用的分类框架可以用来规划自己的优先级。题型大类常见考查点难度区间日常开发相关度字符串与列表切片、反转、去重、统计、格式化入门极高数据清洗基本靠它循环与条件素数、水仙花数、九九乘法表、数列生成入门到进阶高控制流是程序骨架函数与递归参数传递、默认值、递归三要素进阶高代码结构化的基础文件与异常读写文件、编码处理、try/except进阶极高脚本落地必经路面向对象与综合类设计、继承、封装、综合管理系统进阶到综合中高工程化的起点这张表的作用是让你先确认自己处于哪个位置如果字符串和列表的题都要想很久就别急着啃面向对象如果循环题已经闭眼能写就可以把主力时间放在文件和类上面。我自己的习惯是先做一次快速自测把100道题按“看一眼就有思路 / 要想一会儿 / 完全没有头绪”分成三堆再决定从哪一堆开始。直接按题号顺序刷最大的问题在于前30道简单题会消耗大量耐心等碰到真正的重头戏时已经刷不动了。2.1 字符串与列表处理题占比最大决定基本功这类题通常占整份题集的三到四成原因很直接日常开发里处理文本和数据列表是最频繁的需求。判断回文、统计字符出现次数、合并列表、去重保序每道题都在模拟真实的数据清洗操作。很多人觉得这些题简单但“简单”和“写得快且不出错”是两回事。比如判断回文最直观的写法是切片反转后比较但实战里经常有人忘了处理空字符串和大小写问题。我见过不少人在公司笔试里栽在这类基础题上不是不会而是写得太慢、边界想不全。def is_palindrome(s: str) - bool: s s.replace( , ).lower() # 去空格并统一小写让比较更干净 return s s[::-1]这段代码的两个关键点replace( , )处理带空格的句子.lower()统一大小写保证“Racecar”这类词也能正确判断s[::-1]是Python切片反转的惯用写法切片的完整语法是序列[start:stop:step]step 为 -1 就从右往左取整个序列。这个写法比reversed(s)更省事因为后者返回迭代器直接比较前还要再转一次类型。字符串题练到后面你应该形成一种条件反射看到字符串操作先想切片能不能解决再想str方法族里有没有现成工具最后才轮到写循环。这个顺序就是实际开发中追求效率的顺序。2.2 循环与条件逻辑题从语法到思维的过渡这一组的典型题目是素数判断、打印乘法表、求最大公约数。算法本身不复杂但非常考验边界意识和代码组织能力。以素数判断为例很多初学者会写出遍历到 n-1 的版本功能没错但效率难看更常见的坑是忘记处理 1 和 2 这两个特殊值。这类题的价值不在于算法多高深而在于让你养成“先想清楚边界条件再写循环”的习惯。这个习惯在真实项目里直接对应线上bug的多少。def is_prime(n: int) - bool: if n 2: return False if n 2: return True if n % 2 0: return False i 3 while i * i n: # 只需要检查到平方根复杂度降到 O(sqrt(n)) if n % i 0: return False i 2 # 跳过偶数只检查奇数 return True这里的边界处理很关键n 2直接排除 0 和 1n 2单独处理偶数中的特例n % 2 0把偶数全部过滤掉之后循环只检查奇数步长 2循环上界用i * i n而不是i n // 2。这种方式在100题阶段不见得必须自己想到但你必须看得懂因为第三轮变式训练时把普通遍历改成平方根遍历是非常常见的升级方向。循环题练到最后判断标准只有一个面对一个序列你能在一分钟内写出一个不会死循环、不漏边界的遍历。2.3 函数、递归与文件处理题从脚本走向程序结构进入这一组题集开始要求你把代码块拆成函数把重复逻辑抽离出来。常见的考查对象是阶乘、斐波那契、汉诺塔和简单的文件统计。这一阶段的重点不再是“能不能跑通”而是“代码好不好读、对不对”——因为函数一旦定义它的输入输出契约就固定了内部写乱了调用方跟着遭殃。递归题是很多人的第一道坎其实递归就三件事终止条件、递推公式、返回值怎么用。def factorial(n: int) - int: if n 1: return 1 # 终止条件递归到这里就不再往下走 return n * factorial(n - 1) # 递推公式当前值乘以 n-1 的阶乘递归的调用过程是逐层深入再逐层返回参数n每次减 1直到n 1时返回 1然后每一层把结果乘上自己的n返回给上一层。写递归题最容易翻车的地方是终止条件写错或漏写导致无限递归并抛RecursionError。文件处理题则把注意力转向open()的读写模式、编码参数和资源释放。我见过不少人在这类题上败给一行的encodingutf-8具体坑后面第四章会专门展开。这一组题刷完你应该能分清“一个脚本”和“一个结构化的程序”之间的区别后者意味着每个功能都有明确的函数入口和返回值。2.4 面向对象与综合应用题压轴区域的考察重点题集末尾通常会出现一两道综合题比如简单的学生成绩管理、图书借阅或者要求用类来重写前面的某道题。这类题目的特征是把字符串处理、列表操作、文件读写全部串起来还要求你用类来组织数据和行为。考察点有三个会不会设计类、属性和方法怎么划分、数据要不要落盘。综合题放在最后不是没道理的。前面二十道小函数题练的是“单个零件怎么加工”综合题练的是“把零件组装成一台能运转的机器”。我建议做这类题时先画数据流数据从哪里来、存在哪里、中间经过哪些操作、用户通过什么接口触发。把这个流程写清楚再动笔代码结构会顺很多。综合题没有标准答案这也是为什么同一份100题有人写出来是200行的面条代码有人能拆成五个类加一个入口文件——差距不在语法而在设计习惯。练习的最终目的不是把题做完而是借助这道题建立起“先设计再编码”的反射。3. 三轮刷题法把100道题刷透的执行路线直接按题号从1刷到100是最容易半途而废的做法。原因很简单人的记忆会衰减线性推进的刷法刷到第40题时前面30题已经模糊了。我推荐的执行路线是三轮每一轮目的不同时间成本也不同。第一轮求会写第二轮求多种解法第三轮求速度和准确率。三轮下来每道题至少过三遍效果远好于一次性刷三套新题——因为重复是记忆的底层规律而换角度重复则是理解的底层规律。这条路线对新手和熟手都适用区别只在每轮停留的时间长短。3.1 第一轮按知识模块顺序只求独立跑通第一轮的目标不是做出最优解而是每道题都独立写出能跑的代码。按题型模块而不是题号顺序刷先全部搞定字符串与列表再做循环与条件依此类推。这样做的理由是同类题集中练习语法和套路会形成记忆叠加比A类型一道、B类型两道交叉着做更容易上手。每道题给自己定一个时限简单题15分钟中等题30分钟综合题1小时。如果时限到了还没有思路直接看参考答案看懂后合上答案自己默写一遍。这一轮的关键动作是“独立”。哪怕是默写也要保证最终跑出正确结果而不是在编辑器里复制粘贴了事。我见过很多人在这轮翻车一卡壳就翻答案翻完觉得自己会了结果两三天后再看到原题依然写不出来。所以第一轮的验收标准很简单每道题在你自己的电脑上至少运行通过一次并且运行前能口头说出你的思路。如果只能说“我照着答案敲的”这题就不算过隔天重做。3.2 第二轮重写同一道题强迫自己换解法第二轮在第一轮全部完成之后开始。此时离第一道题已经隔了一段时间记忆刚好处于“有点印象但手生了”的状态最有利于重写。这一轮的要求比第一轮高一档同一道题至少写出两种不同解法。比如回文判断第一轮用切片第二轮试着用循环双指针列表去重第一轮用集合第二轮用dict.fromkeys保持顺序斐波那契第一轮写递归第二轮改用迭代加记忆化。换解法的目的不是炫技而是让你理解同一个问题背后不同的复杂度代价。仍以去重为例def dedup_keep_order(items): return list(dict.fromkeys(items)) # 字典保持插入顺序实现去重且不换位这个写法利用了Python 3.7之后字典按插入顺序保存的特性fromkeys把列表元素作为键构建字典重复键自动覆盖再转回列表就实现了去重保序。相比手写循环加set判断代码短了三分之二复杂度仍然是 O(n)。第二轮做完你应该能评价每种解法的适用场景数据量小时选最简洁的数据量大时考虑内存和耗时面试时选最容易表达思路的。把这些对比记进错题本比单纯多刷十道新题更有用。3.3 第三轮改参数、限时间模拟真实环境第三轮是查漏和提速度的阶段建议在笔试或面试前两周进行。做法是把每一道题的条件换掉题目要求统计字母你就改成统计中文字符要求整数序列你就改成浮点数要求从代码里读数据你就改成从CSV里读。换完条件给每道题设定正常时间的一半比如原来30分钟的题现在15分钟内必须写出可运行代码。这样做的价值在于你训练的是“面对新需求时调用已知套路”的能力。真实开发的题目永远不是练习题的原文但知识点的组合方式是相似的。比如练习题里倒序输出字符串变形后可以是倒序输出列表中的每条路径练习题里统计词频变形后可以统计日志里的异常类型次数。第三轮我还会给自己加一条硬性要求写完必须用几个边界值测一遍包括空列表、只有一项的列表、全相同元素的列表。这一轮跑练下来面对没见过的题就不会慌因为你清楚自己手里有哪些可调用的底牌。4. 五类常考题型精讲代码、参数与边界前面两章给了全貌和路线现在落到具体题上。下面五类几乎在每份Python练习题集里都会出现我把常见写法、关键参数和最容易忽视的边界一次性讲清楚刷题时可以直接对照。每段代码都可以直接复制进解释器跑跑完再改参数试几个变体比干读文字效果好得多。4.1 字符串处理回文判断与格式化的边界字符串题考察最多的是三块切片、方法族、格式化。切片的完整语法是序列[start:stop:step]三个参数都可省略step 为负时反向取值。回文判断最简洁的写法就是s s[::-1]但要注意处理特殊输入空字符串按定义是回文单字符也是回文带大小写和标点时要不要忽略取决于题意。我的习惯是在函数开头就把数据“洗”干净用一个方法链完成清洗。def normalize(s: str) - str: return .join(ch for ch in s.lower() if ch.isalnum()) # 只留字母和数字这个工具函数用isalnum()判断每个字符是否是字母或数字从而丢弃空格和标点结果全部转成小写之后再比较回文就干净多了。isalnum对中文同样生效所以处理中文文本不会误伤。格式化方面f-string 是首选f{user}: {score:.2f}这类写法直观易读老式的%格式化和format()方法可以认识但新代码里不值得再写练习题中遇到直接用 f-string 改写。字符串题练到这个程度就具备了处理真实文本数据的能力。4.2 列表与字典去重、排序、计数的惯用写法列表字典题最经典的三个需求是去重、排序、统计出现次数。去重最简单的是set()但会丢失顺序保持顺序的写法就是上一章说的dict.fromkeys()。排序用内置sorted它的key参数可以接收 lambda 或函数指定排序依据统计词频最优雅的写法是collections.Counter它本身就是字典的子类可以直接取出现次数最多的几个元素。from collections import Counter words [python, java, python, go, python, java] counter Counter(words) most_common counter.most_common(2) # 返回出现次数最多的前2个most_common(2)返回的是[(python, 3), (java, 2)]这样的列表内部用堆排序实现数据量大时依然高效。刷题时如果发现自己正在手写嵌套循环做计数先停下来想想Counter能不能用。不仅代码短而且可读性好。这三类需求对应的工具函数应该达到“闭眼能写”的程度去重保序用dict.fromkeys排序用sorted(key...)计数用Counter。4.3 递归与数学题斐波那契三种写法的取舍数学类题目最常见的代表是斐波那契数列。初学者先学递归但递归直接实现有一个肉眼可见的坑大量重复计算。用朴素递归算第40个斐波那契数会重复计算成千上万次慢到让人怀疑电脑坏了。标准解法有三种朴素递归、记忆化递归、迭代。三者的代码量和效率差异巨大练习题的价值正在于让你一眼看穿它们的取舍。def fib_iter(n: int) - int: if n 1: return n a, b 0, 1 for _ in range(2, n 1): a, b b, a b # 滚动更新前两项往前进一位 return b迭代版的思路是同时维护前两个值每次循环把第二项当作新的第一项把两项之和当作新的第二项。参数n表示第几位循环从 2 开始到n结束所以n2时循环只跑一次就返回 1结果是正确的。这种滚动更新避免了递归的函数调用开销和重复计算时间复杂度 O(n)空间 O(1)。刷题时的建议是先用迭代写保证正确再用记忆化字典写递归作对比不要用朴素递归提交需要运行的题它在 n 稍大时会直接卡成假死。4.4 文件读写与异常处理编码和资源释放的坑文件题在练习阶段最容易出现两种翻车一是不处理编码导致读中文乱码二是不用with管理文件句柄导致资源泄漏。正确且省心的写法是用with open()上下文管理器并显式指定编码。with open(data.txt, r, encodingutf-8) as f: lines f.readlines() # 按行读取到列表每行带换行符open的三个关键参数在这里都出现了r是只读模式encodingutf-8显式指定字符集with语句保证代码块结束时文件自动关闭。练习时如果把编码参数省掉Windows 默认会按本地编码解码中文文本大概率报UnicodeDecodeError或出现乱码这个错在真实项目里也一样常见。异常处理方面练习题通常只需要捕获FileNotFoundError或通用的OSError不要用空except:吞掉所有异常否则出了问题没法定位。文件题练到位的一个标志是你不再把open()和close()分开写而是条件反射地用with。4.5 面向对象设计题从函数式到类的改造思路面向对象题并不是要求把所有题目都写成类而是考察你能否识别“数据和行为应该绑定在一起”的场景。典型例子是银行账户类账户有余额属性有存款、取款方法。如果把余额当成全局变量写在函数外面两个账户就会互相干扰设计成类每个实例有自己独立的余额方法操作自己的状态这才是面向对象的出发点。class BankAccount: def __init__(self, owner: str, balance: float 0.0): # 构造方法初始化账户 self.owner owner self.balance balance def deposit(self, amount: float) - float: if amount 0: raise ValueError(deposit amount must be positive) self.balance amount return self.balance def withdraw(self, amount: float) - float: if amount self.balance: raise ValueError(insufficient funds) self.balance - amount return self.balance这个例子里__init__是构造方法self.owner和self.balance是实例属性deposit、withdraw是方法。两个关键设计存款和取款都在入口处校验参数合法性然后才修改状态这比裸改属性安全得多取款先检查余额够不够避免出现负数。写这类题时可以先不急着写类先用函数写一版跑通后问自己一个问题“哪些数据是多个操作共用的”答案就是应该放进self的属性。从函数到类的改造过程比直接背类模板更容易建立工程直觉。5. 刷这100道题的避坑指南五处最容易翻车的地方下面这些坑是我刷题和指导别人刷题时反复遇到的真实问题每条都按“现象、原因、解决”展开。你可以把它当排查手册用遇到类似情况先对照原因再按解决办法走能省下大量瞎折腾的时间。5.1 开着答案抄代码抄完十题忘十题现象做题时没思路就马上打开答案看照着敲一遍运行通过后自我感觉良好可几天后原题重现依然写不出完整代码。原因把“看懂答案”当成了“会做题”复制操作没有经过大脑重新编码记忆留存率极低。解决把参考答案当成最后手段先给自己定15到30分钟的思考时限时间到了没思路才看答案看完合上答案凭理解默写一遍并且改掉一两个参数重新运行。默写不出来就隔天再来直到能独立写对为止。这个流程看似慢实际是最不浪费时间的刷法。5.2 只测正常输入不测边界值现象代码对常规输入运行正常一旦输入空字符串、空列表、单元素列表或超大整数程序要么抛异常要么结果错误。原因练习题的样例输入通常很友好形成了“样例过了就算会”的错觉忽略了真实数据里那些让人头疼的角落。解决每道题写完都强制追加四个边界测试空值、单元素、重复元素、极大的数。assert is_palindrome() is True assert is_palindrome(a) is True assert is_palindrome(A man a plan a canal Panama) is True assert is_palindrome(hello) is Falseassert是Python内置的断言语句条件为假时直接抛AssertionError不需要写额外的输出。把它放在函数定义后面测试用例就固化在代码里之后改动函数可以立刻回归。养成这个习惯后你写代码的“脆度”会明显下降线上问题大多不在主流程而在边界条件下没人处理的那个分支。5.3 环境与题解版本不一致把旧语法当现代写法抄现象把某些旧题解里的print语句、xrange、unicode声明原样搬进现代解释器不是报语法错误就是行为不对。原因练习题流传年代久远网上版本混杂着 Python 2 时代的代码不加分辨地复制就会踩中版本差。解决确认自己跑的是 Python 3写作时遵守几条红线print必须是函数形式用range不用xrange字符串统一用str整除用//。遇到题解出现这类旧语法在脑内翻译成 Python 3 再写不要直接复制。运行前习惯性执行python --version看一眼解释器版本能少排查一大类语法问题。5.4 遇到报错不看堆栈凭感觉乱改现象代码报错后不去读报错信息而是随机加打印语句、调整代码顺序改完再跑报错变了就开始焦虑。原因把解释器当黑匣子不知道Python的异常堆栈第一行就指出了出错文件和行号最后一行说明了异常类型。解决把报错信息从头读到尾先看Traceback里的文件路径和行号定位到具体代码行再看异常类型IndexError是索引越界KeyError是字典缺键TypeError是类型不匹配AttributeError是对象没有该属性。这些都是最常见的异常看懂了就等于拿到了排查路线图乱改代码只会把问题越搞越复杂。5.5 一遍刷完不归档回头无处可查现象刷过一遍之后当时会做的题过几个月再看毫无印象也没有任何笔记可查只能从头再刷。原因刷题过程只产生了运行成功的代码没留下“这道题考什么、我哪里卡过、最优解是什么”的痕迹。解决建一个轻量错题本不需要复杂工具一个带日期和题号的文件即可。07-13 题16 回文判断 卡点: 忘记忽略大小写和空格 解法: 先清洗字符串再比较反转结果 收获: 字符串比较前先做规范化笔记的要点是记录“卡点”而不是抄代码因为卡点才是你真正的盲区。面试前翻一遍错题本比重新刷一百题效率高得多。我自己的习惯是每刷完一组就把笔记整理进一个统一文件标注题型和解法这样100题刷完留下的不只代码还有一份自己的知识地图。6. 把100道题变成能力清单面试前最高效的复习方法最后这个技巧是我把题集转化成复习工具时最常用的做法刷完100道题把产出整理成三样资产——能跑的代码、错题本、能力清单。清单按知识模块标注熟练度字符串处理熟练列表字典熟练递归需要再练文件读写熟练面向对象一般。用途是定向补漏不是平均用力。面试前三天做一次15分钟快速自测随机抽10道题不看答案每题限时写完用边界值自测对照错题本看哪个模块失分最多当天只补这些模块。产出还能更进一步。把做过的综合题改造成简历上的模拟项目比如学生成绩管理系统或记账小工具整理成小仓库。同样代码量比写“熟悉Python”更有说服力面试时还能直接打开讲设计思路。我的血泪经验是题照抄一百遍不如把其中一道改成自己的需求再写一遍——前者让你记住题后者让你掌握迁移能力。刷题本身不是目的目的是形成条件反射看到一个需求能快速匹配到对应的数据结构和解法套路。题集的价值恰在这里它把知识点替你排列好了你要做的是用三轮训练把这些排列内化成自己的反应链路。希望这份路线能帮你少走弯路。刷透100道题之后你会发现写脚本不再需要盯着屏幕发呆面试遇到陌生题目也有底气。先定个小目标今天从第一道字符串题开始别让它继续躺在收藏夹里。希望帮到你。本文还有配套的精品资源点击获取