100道Python经典练手题:从基础语法到算法实战,附精讲与刷题路线

发布时间:2026/9/17 8:46:00
100道Python经典练手题:从基础语法到算法实战,附精讲与刷题路线 如果你正在学Python大概率已经见过不少“200道练习题”“500道面试题”的资源。但真练下来你会发现大部分题单要么简单到只有print要么直接跳进算法题中间缺少一个循序渐进的过程。今天说的这套“100道Python经典练手题”是这些年我实际带新人时反复调整过的一套题单从print语句、变量交换开始一路覆盖数据类型、循环、函数、字符串、文件、面向对象、标准库最后落到二分、排序、动态规划和综合项目。每道题都标了核心考点能直接对着练、对着查、对着复盘。这套题单适合谁刚装好Python、连VSCode或PyCharm还没配明白的新手可以从第1题慢慢推已经能写循环和函数的初级开发者可以重点刷函数模块之后的内容准备面试的人可以直接跳到栈、装饰器和动态规划题目。它解决的核心问题只有一个让你不是“看过Python”而是“真能用Python写出东西”。下面我就把这套题单的整体设计、完整分类、典型精讲和刷题方法一次性摊开讲。1. 为什么说这100道题值得“苦练”1.1 练手题和面试题、项目题有什么区别很多人学Python有个误区要么只看语法教程不动手要么一上来就做爬虫、Web项目结果卡在环境配置和框架细节里语法反而没打牢。面试题偏重“考察”用到的知识面窄而且经常有刁钻边界项目题偏重“工程”需要前置掌握的东西太多不适合拿来当日常训练。练手题的定位正好在两者之间每道题目标明确、单点突破、反馈快写完一行代码马上能看到结果非常适合用来建立“代码手感”。“苦练”这两个字重点在“苦”上。Python语法看起来简洁但真到用的时候你会发现列表切片越界、闭包变量绑定、装饰器参数传递、浅拷贝深拷贝全是坑。这些坑不是看书能看出来的必须亲手踩一遍再爬出来记忆才深刻。我见过太多人“眼睛会了手不会”一到自己写就报错原因就是练得不够。这100道题就是把Python里最容易出问题的知识点拆成一个个小任务让你在安全的环境里反复摔打。另外练手题还有一个容易被忽略的价值它能帮你积累“可复用代码片段”。比如第57题的括号匹配核心是一个栈的使用模板后面做计算器、HTML标签解析都能用到第44题的装饰器计时稍微改改就能变成项目里的日志装饰器。刷题的意义不是背答案而是把这些高频片段变成肌肉记忆。1.2 这套题单的整体设计思路这100道题不是随便凑数的。第一覆盖了Python入门的全部核心语法节点基础输入输出、条件循环、列表字典字符串、函数、文件异常、面向对象、常用标准库、基础算法一共9大模块。第二难度按“认知负荷”递增从单行代码能解决的问题逐步过渡到需要拆解状态、设计数据结构的题目。第三每个模块内都有几道“硬菜”比如螺旋矩阵、汉诺塔、装饰器计时、括号匹配、最大子数组和这些题不是简单CtrlC能抄过去的必须真正理解思路才能写出来。选这些题的标准也很简单要么是日常写代码最高频用到的能力比如字符串处理、字典操作、文件读写要么是面试常考的基础算法比如二分查找、快排、动态规划。那些偏门、冷门、只在竞赛里存在的题目我一律没放进去。把这100道题吃透不敢说成为Python大师但应付日常工作开发、大部分初级和中级岗位面试笔试完全够用。提示这套题单建议按顺序刷但不用平均用力。如果你时间有限优先保证函数模块和算法模块的题目质量这两块是新手最容易“断层”的地方。2. 一百道经典练手题全题单按模块分类配核心考点下面把100道题按模块完整列一遍每道题都标注了核心考点。表格里的描述就是解析线索刷题时先按考点自己写写不出来再回来看对应章节的精讲效果最好。2.1 基础语法与输入输出第1-10题这个模块是热身区目的不是让你学会print而是让你熟悉Python的运行方式、类型转换、字符串格式化和条件分支的基础写法。新手别觉得简单就跳这里有个隐藏能力把“人话描述的需求”翻译成“代码操作”这种翻译能力从第1题就开始训练了。题号题目核心考点1改造版Hello Worldprint的sep、end参数与转义字符2交换两个变量的值临时变量、元组解包、加减法交换3数字类型转换“变形记”int/float/str互相转换及异常输入处理4从键盘输入半径计算圆面积周长input、math模块、格式化保留小数5反转一个三位数120反转为21取余取整运算、字符串切片6字符编码查看与转换ord()、chr()、ASCII与Unicode的关系7摄氏温度与华氏温度互转分支判断、公式计算8格式化输出学生成绩表f-string对齐、整数与浮点数格式控制9时间格式互转时分秒与总秒数乘除取整、复合赋值10BMI计算器多分支条件、浮点数精度处理2.2 数据类型与序列操作第11-25题列表、字典、字符串、元组是Python里最常用的四种数据容器大部分程序本质上都是在操作它们。这个模块的题不会给你现成的API提示比如“列表去重”不允许直接看set方法的用法要求你自己推导矩阵转置要求你理解嵌套列表的索引规律。这个模块刷完Python的数据结构基本功就稳了一半。题号题目核心考点11列表去重且保持原顺序集合去重与列表遍历的顺序控制12统计字符串中每个字符的出现次数字典计数、collections.Counter13不用内置函数求列表最大值最小值平均值手写遍历、初始化哨兵值14判断两个字符串是否为字母异位词排序后比较、计数器比较15找出列表中第二大的数一次遍历、边界值处理16自己实现列表反转切片步长为负、双指针交换17字符串压缩aabbbc变为a2b3c1循环拼接、相邻字符比较18字典按值排序sorted函数、lambda表达式19矩阵转置嵌套列表、zip拆包20求两个列表的交集、并集、差集集合运算、类型转换21元组拆包提取学生信息多变量赋值、下划线占位22统计英文句子中的单词数split切分、正则去标点23嵌套列表扁平化递归、循环逐层展开24求多个字符串的最长公共前缀逐位比较、zip配合enumerate25生成n阶螺旋矩阵四方向边界模拟、while循环状态控制2.3 条件与循环逻辑第26-40题这个模块是经典“编程思维”训练区几乎不依赖任何高级特性全靠对循环、分支、边界条件的掌控。很多人写代码容易“差一个数”或者“多跑一次”核心就是循环条件没想清楚。九九乘法表、素数、水仙花数这些题看起来老土但它们能让你的循环肌肉记忆变得非常扎实。题号题目核心考点26判断闰年if条件组合、模运算27百分制成绩转等级制多分支判断、逻辑运算符28求所有三位水仙花数拆分个十百位、幂运算29打印九九乘法表嵌套for、格式化对齐30斐波那契数列前n项递推迭代、变量滚动更新31判断素数并输出100以内全部素数试除法、循环提前break32求最大公约数和最小公倍数辗转相除法、公式推导33判断整数和字符串是否为回文反转比较、双指针34十进制转二进制、八进制、十六进制除基取余、循环拼接35打印等腰三角形、菱形、空心正方形嵌套循环、空格与星号数量规律36猜数字游戏random随机数、while循环与条件反馈37鸡兔同笼知道头脚数求数量穷举法、多元方程模拟38将一个整数分解为质因数while嵌套、质因数递增判断39小球自由落体反弹高度与总路程等比数列递推、浮点累加40统计1到n中某个数字出现的总次数逐位拆解、循环计数2.4 函数与模块第41-52题很多初学者写代码喜欢把所有的逻辑堆在一起换个数就得改代码。到函数模块要求你用参数和返回值把逻辑“装进盒子”这是从“写脚本”到“写程序”的分水岭。默认参数陷阱、*args、装饰器、闭包、生成器这些不仅是考试重点也是实际项目里每天都会碰到的特性。这12道题值得反复咀嚼。题号题目核心考点41用牛顿迭代法实现自己的sqrt函数函数定义、迭代逼近42默认参数使用列表的陷阱题可变对象做默认参数的问题43用*args和**kwargs写求和函数参数收集、字典展开44装饰器统计函数执行时间装饰器结构、time模块45递归实现阶乘并设置递归保护递归出口、sys.setrecursionlimit46lambda结合sorted对学生信息排序高阶函数、key参数47用map/reduce/filter清洗成绩数据内置高阶函数组合48生成器实现斐波那契数列yield关键字、惰性求值49闭包计数器闭包保存状态、nonlocal声明50自定义迭代器模拟range函数迭代器协议、iter__与__next51偏函数实现批量单位转换functools.partial52汉诺塔递归实现并输出移动步骤递归拆解、参数交换2.5 字符串进阶与正则第53-62题字符串处理在数据分析、爬虫、日志分析里是高频场景而这部分恰恰是很多自学者的薄弱区。正则表达式单独拿出来讲题不多但配合字符串方法能解决90%以上的文本处理需求。第57题括号匹配是“栈思想”的入门题第60题最长不重复子串则是滑动窗口的雏形建议多花时间。题号题目核心考点53反转句子中单词顺序但保持单词内部不变split切分、列表反转、join拼接54用四种方法去掉字符串中的指定字符replace、列表推导、filter、正则55驼峰命名转下划线命名正则边界、re.sub回调56手机号中间四位脱敏字符串切片拼接、re.sub替换57判断多种括号是否匹配栈、字典映射58实现简易模板字符串解析find定位、replace、正则分组59统计字符串中每个字符首次出现的位置字典记录、index陷阱60找出字符串中最长不重复子串滑动窗口、集合去重61单词首字母大写并保留连续空格title方法的替代实现62下划线命名与驼峰命名互相转换正则分组、字符串拼接2.6 文件处理与异常第63-72题文件操作是Python最实用的能力之一读写配置、日志分析、批量处理文件都是这个场景。这10道题让你把with语法、异常捕获、CSV和JSON处理全部过一遍。第66题自定义异常和第72题递归目录遍历在真实项目里尤其常见建议按“能直接交给同事用的标准”来写。题号题目核心考点63读取大文件统计行数和单词数with open、流式读取64复制文件并比较大小shutil模块、文件流读写65按日期切分日志文件正则提取日期、动态文件名66自定义“余额不足”异常继承Exception、raise与except67try/except/else/finally资源释放完整异常结构、finally作用68读取JSON配置并与默认配置合并json模块、字典update归并69CSV文件读写并统计平均成绩csv模块、DictReader70合并多个txt文件并去重保存列表集合操作、文件批量处理71检测文件编码并转成UTF-8codecs、编码错误处理72递归遍历目录查找指定扩展名文件os.walk、os.path.join2.7 面向对象与设计模式第73-85题面向对象是Python进阶绕不开的一块。这里不要求你背概念而是直接写类银行账户、向量运算、单例、描述符、链表、栈队列……把这些代码写过一遍你才能真正理解“类是对数据和行为的封装”这句话。第80题描述符和第82题观察者模式有一定难度但无论做框架开发还是应对面试都值得啃下来。题号题目核心考点73设计银行账户类存款、取款、流水类属性与实例方法74实例方法、类方法、静态方法对比classmethod与staticmethod75继承和多态不同形状计算面积父类抽象、子类重写76用property实现温度自动转换property、setter77用__slots__限制动态属性内存优化、属性白名单78向量类支持加法和乘法add、__mul__运算符重载79单例模式实现new、类变量控制80描述符实现属性类型校验get、set81工厂模式按类型创建对象条件分支创建产品类82观察者模式事件发布订阅列表维护观察者、消息通知83链表节点类并实现反转链表节点引用、指针遍历84用类实现栈和队列列表操作、先进后出/先进先出85学员管理系统类协作、循环菜单、列表操作2.8 常用标准库与算法思维第86-100题最后15道题是“拔高区”先熟悉datetime、random、collections、itertools、argparse、logging这些日常开发离不开的标准库再上二分查找、排序算法、动态规划最后落到一个综合性命令行项目上。第100题负担很重但它把前面几十道题全部串了起来相当于一次大考。题号题目核心考点86计算两个日期相差天数和星期几datetime模块、date对象87生成6位验证码字母数字random.choice、字符集拼接88用Counter统计词频并输出TOP10Counter、most_common89笛卡尔积生成扑克牌组合itertools.product90用lru_cache加速递归斐波那契functools.lru_cache91用argparse写命令行加法工具命令行参数解析92os.path和pathlib路径操作练习路径拼接、判断文件目录93logging日志同时输出到文件和终端logger配置、Handler绑定94二分查找递归与非递归有序数组查找、边界更新95手写冒泡、选择、插入排序三类排序实现与区别96手写快速排序分治思想、基准值选择97爬楼梯问题动态规划入门状态转移方程98求最大子数组和Kadane算法连续子问题、贪心递推99实现字典树Trie节点嵌套字典、前缀查找100命令行学生成绩管理系统增删改查统计JSON持久化菜单3. 六道高频经典题精讲从思路到完整代码题单列完了但光有题目没有答案收藏了也练不动。下面挑6道覆盖不同难度层的经典题把完整的思考过程和代码写出来。每道题我都会先说“拿到题怎么想”再给代码最后讲易错点这样你能直接照着自己的思路对照。3.1 变量交换的三种写法基础题里藏着大知识点第2题“交换两个变量的值”看似简单但能拆出三种写法。新手通常只会临时变量法写着写着就忘了变量覆盖的顺序进阶者知道Python有元组解包老手则明白在某些底层场景里可以用加减法避免额外空间但要注意溢出风险。a, b 3, 5 # 方法1临时变量 tmp a a b b tmp # 方法2Python独有的元组解包最推荐 a, b b, a # 方法3加减法仅限数值类型 a a b b a - b a a - b这道题真正想考的是“对变量的理解”变量是对象的引用交换的本质是重新绑定引用。元组解包之所以成立是因为右边先构造了一个临时元组(b, a)再按位置依次赋值给a和b所以不需要担心覆盖问题。新手写方法1时最容易犯的错是写成a b; b a结果两个变量都变成同一个值。这不是粗心而是没有建立“每一步执行后变量里存什么”的追踪意识。建议新手把每行代码执行后的a、b值都写在纸上练两道题就能纠正过来。3.2 温度转换分支判断的标准范式第7题“摄氏温度转华氏温度”本身就是一道完整的程序题要有输入、有计算、有输出还需要考虑用户输错的情况。很多人只写核心公式就收工但实际开发中输入数据是不可信的所以正规写法必须处理异常。try: celsius float(input(请输入摄氏温度: )) except ValueError: print(输入错误请输入数字。) exit() fahrenheit celsius * 9 / 5 32 print(f{celsius:.1f}℃ {fahrenheit:.1f}℉)float(input(...))这一步融合了input和类型转换两个知识点。转换失败抛出的ValueError由try/except接住并给出友好提示这比让程序直接崩溃好得多。如果还想扩大范围可以加一个单位参数让用户输入“36.5C”或“97.7F”自动判断方向这正好把第27题的多分支也练了。这种“先做核心功能再补异常处理最后扩展交互”的流程就是我说的标准范式。3.3 螺旋矩阵四方向模拟是面试常客第25题“螺旋矩阵”是典型的模拟类题目思路不复杂难在边界控制。面试时这种题最能看出候选人写代码的细致程度。想象一个n行n列的矩阵你拿着笔从1开始顺时针画圈。程序的做法就是把这个画圈过程翻译成四个方向的循环从左到右填充上边从上到下填充右边从右到左填充下边从下到上填充左边然后缩小边界继续下一圈。def spiral_matrix(n): matrix [[0] * n for _ in range(n)] top, bottom, left, right 0, n - 1, 0, n - 1 num 1 while top bottom and left right: for col in range(left, right 1): matrix[top][col] num num 1 top 1 for row in range(top, bottom 1): matrix[row][right] num num 1 right - 1 if top bottom: for col in range(right, left - 1, -1): matrix[bottom][col] num num 1 bottom - 1 if left right: for row in range(bottom, top - 1, -1): matrix[row][left] num num 1 left 1 return matrix for row in spiral_matrix(4): print(row)这段代码里有三个关键点。第一[[0] * n for _ in range(n)]是创建n阶零矩阵的标准写法不能写成[[0] * n] * n后者会让所有行指向同一个列表改一行全变。第二每完成一个方向对应的边界就要收缩比如填充完上边后top 1。第三后两个方向的循环要加边界判断否则n为奇数或循环到最后一行时会重复填充。运行结果的第4行会是[10, 11, 12, 1]对照这个结果能判断自己的方向控制是否正确。3.4 用装饰器给函数计时函数进阶必过的一关第44题“装饰器统计函数执行时间”是Python进阶最经典的一道题。第一次接触装饰器的人很容易懵因为代码里套了三层函数。拆开看其实不难timer是“装饰器工厂”接收一个原函数funcwrapper是“增强版函数”它先记录时间再调用func最后打印耗时并返回结果timer语法糖就是告诉Python“执行下面这个函数时自动用wrapper替换它”。import time def timer(func): def wrapper(*args, **kwargs): start time.perf_counter() result func(*args, **kwargs) end time.perf_counter() print(f{func.__name__} 执行耗时: {end - start:.6f} 秒) return result return wrapper timer def sum_square(n): total 0 for i in range(1, n 1): total i * i return total print(sum_square(1000000))用time.perf_counter()而不是time.time()是因为perf_counter专门用于测量短时间间隔精度更高受系统时间调整的影响更小。这里有一个高频易错点wrapper的参数必须写成*args, **kwargs因为被装饰的函数可能带任意参数如果不做参数收集原函数的参数就会传不进去。另一个易错点是wrapper内部必须return result否则原函数的返回值会被吞掉写出来变成了None。第47题的map/reduce/filter和第90题的lru_cache本质上都是同一套“函数包装”思想理解了装饰器那些题都会顺畅很多。3.5 括号匹配用栈解决字符串问题第57题“判断括号是否匹配”是栈最经典的应用。很多人在学校学过栈的定义但不知道怎么写代码。思路一句话遇到左括号就压栈遇到右括号就检查栈顶是不是对应的左括号是就弹出不是就返回False。最后栈为空才说明全部匹配。def is_valid(s: str) - bool: stack [] pairs {): (, ]: [, }: {} for ch in s: if ch in ([{: stack.append(ch) elif ch in )]}: if not stack or stack[-1] ! pairs[ch]: return False stack.pop() return not stack print(is_valid(()[]{})) print(is_valid(([)])) print(is_valid(({[]})))三种典型输入对应三种结果()[]{}返回True因为每种括号都是标准的闭合([)]返回False虽然括号数量成对但交叉嵌套是非法的({[]})返回True正确嵌套。这里最容易漏的处理是not stack判断当输入只有右括号比如}时栈为空直接访问stack[-1]会抛IndexError所以必须先把“栈为空”排除掉。理解了这道题后续做“逆波兰表达式求值”“HTML标签匹配”都是换汤不换药。3.6 最大子数组和从暴力到动态规划的思维升级第98题是算法模块的入门大师题给定一个整数数组求其中连续子数组的最大和。比如[-2, 1, -3, 4, -1, 2, 1, -5, 4]的最大子数组和是6对应子数组[4, -1, 2, 1]。暴力法需要三重循环枚举所有子数组再求和复杂度O(n^3)而Kadane算法能把复杂度降到O(n)核心就一句话要么扩展当前子数组要么以当前元素重新开始取两者中较大的那个。def max_subarray(nums): max_ending_here nums[0] max_so_far nums[0] for num in nums[1:]: max_ending_here max(num, max_ending_here num) max_so_far max(max_so_far, max_ending_here) return max_so_far print(max_subarray([-2, 1, -3, 4, -1, 2, 1, -5, 4]))手动推演一遍就明白了。遍历到4时max_ending_here会变成4因为4比4 (-2)更大此时表示“我决定从头开始一个新的子数组”遍历到2时max_ending_here变成5因为2比2 3小扩展它。关键是理解max_ending_here保存的永远是“以当前位置结尾的最大子数组和”一旦它变成负数后面的元素带着它只会更小不如重置。这就是状态转移方程dp[i] max(nums[i], dp[i-1] nums[i])的直观理解也是做各种动态规划题的基本思维模型——先找子问题再写递推关系最后优化空间。4. 刷题方法、时间规划与避坑指南4.1 按基础分层的刷题路径这套题单虽然是从0开始排的但不同基础的人刷法应该不一样。零基础的人老老实实从第1题刷到第40题先不碰函数和面向对象。这个阶段的目标是熟练使用变量、循环、列表和字典遇到报错会看traceback。第25题螺旋矩阵如果卡住了可以先放着往后学等循环理解更透再回头补。已经有语法基础、只是没做过题的人重点在函数模块之后的内容。第41到第85题是提升区尤其第42、43、44、49、57、70、76、80题分别对应函数参数、装饰器、闭包、栈、文件、property、描述符等高频难点。做题时不要追求“跑通就行”要问自己“换一种写法行不行”“如果输入特殊值会怎样”。准备面试的人先做第57、60、84、94、95、96、97、98、100题。这9道题直接对应栈、滑动窗口、队列、二分、排序、动态规划、综合设计是笔试里出现频率最高的一批。做完之后建议把时间和空间复杂度标注在代码旁边面试官问起来能对答如流。4.2 四周实战时间规划表每天留出1到1.5小时按下面的节奏推进四周刚好能过完一遍完整题单。时间段刷题范围核心目标复盘重点第一周第1-30题打牢语法基础和循环逻辑运行报错能不能独立看懂第二周第31-57题掌握函数、字符串、正则、栈能否不看资料写出装饰器和括号匹配第三周第58-85题攻克文件和面向对象类设计是否合理对象间是否解耦第四周第86-100题标准库与算法入门能否独立完成第100题综合项目第一周和第而周第二周的任务是“量”后两周是“质”。第三周开始每道题写完要顺手补充测试用例比如第60题的最长不重复子串至少测空字符串、全相同字符、全部不重复三种情况。第四周的第100题不要直接写代码先画一个功能清单把“增删改查、统计平均分、JSON保存”拆成多个函数再逐个实现这就是从刷题到项目的过渡。4.3 新手必踩的6个Python坑刷题过程中下面6个坑几乎每人都会踩至少一次这里提前列出来等于帮你省下几个小时的排查时间。默认参数使用可变对象。def append_item(item, lst[]): lst.append(item); return lst第二次调用时列表还保留着上一次的数据。原因是默认参数在函数定义时只创建一次解决方法是默认值写成None函数内部再赋值。把和is混用。比较值is比较对象身份。小整数驻留、短字符串驻留等场景下两者结果偶尔相同但列表、字典等可变对象绝不能这样用。在遍历列表的同时删除元素。for x in lst: lst.remove(x)会跳元素因为删除后索引自动前移。正确做法是遍历副本for x in lst[:]或者用列表推导式过滤。对不可变类型做“原地修改”。字符串的replace、upper等方法的返回值才是新字符串不少人忘了接住返回值结果发现原字符串“没变”。浅拷贝误伤嵌套列表。new_list old_list[:]只拷贝了外层内层列表仍然是同一对象需要深拷贝时用copy.deepcopy。整数除法结果不对。两个整数用/会得到浮点数如果希望整除要用//这个坑在写递归除法或需要精确整数结果的场景里特别隐蔽。4.4 拿到一道题之后的标准思考流程刷题盲目上手容易越写越乱。我建议每道题都过一遍固定流程第一步读题后先把输入和输出写下来包括边界情况第二步用自然语言描述解法比如“先遍历列表遇到大于max的就更新max”第三步构思需要几个变量变量的初始值是什么第四步写代码并自测用例第五步复盘这段代码的时间复杂度和空间复杂度。以第40题“统计1到n中数字x出现次数”为例。拿到题先写边界n1时返回什么x0时怎么处理x大于9时怎么处理。然后思考解法最简单的是把每个数字转成字符串后count但这样不够高效进一步优化是逐位分析直接算每一位上x出现多少次。从“能跑”到“跑得更快”这个升级过程就是面试官真正想考察的能力。所以刷题时别满足于写出一种解法有条件就再问自己一句能不能少一层循环能不能省掉临时变量这种提问习惯比多刷50道题都管用。这100道题我自己带人刷过好几轮最大的体会是重要的不是“看起来懂”而是“合上书能不能写出来”。每道题独立写对一遍再隔一周不看答案重写一遍才算真正消化。把做错的题单独存成一个文件记录错误原因两周后回头重新做比连续刷完两遍新题效果好得多。到最后你把第100题完整写出来再回头翻第一周的代码会明显看到自己逻辑清晰了多少。那就是“苦练”最大的回报。