资讯动态

Python经典100题精讲:前10道入门必刷,避开常见坑

发布时间:2026/9/9 3:47:46 来源:尧图企业网站定制
如果让我只推荐一套Python入门练习题我大概还是会搬出那套老经典的Python经典100题。它不是什么神书也没有花哨的项目但就是能在你学完基础语法之后帮你把“看懂”变成“会写”把“好像懂了”变成“真能跑通”。这篇文章先把第1题到第10题拆开揉碎讲清楚所有代码我都用Python 3.10跑过你可以直接照着敲。你可能觉得前10题看起来简单但真正的坑往往就藏在这种简单题里——比如第7题列表复制十个新人里有七个会踩坑。不管你是刚学完循环和列表的新手还是工作后想回来补一补基础的人这10道题都值得花一个下午亲手过一遍最好还能动手改一改。这次我不打算只给答案。每道题都会先讲清楚“为什么这么想”再给代码最后标注我实际带人时见过的高频错误。这样你抄作业也抄得明白。1. 内容整体设计1~10题在100题中的定位1.1 这套题为什么能一直流传这套Python经典100题的前身是很早之前流传开的C语言100例后来被一代代人改写成Python版本。虽然题目描述还带着一点老教程的味道但它的编排逻辑非常扎实前10题只涉及输入输出、类型转换、分支、循环、列表、简单模块调用几乎不依赖任何第三方库。换句话说你刚学完基础语法就能开始刷刷完又能反过来加深对基础语法的理解。我特别喜欢这套题的原因在于它不靠堆砌知识点来制造难度而是用非常简单的场景逼着你去思考。比如第1题数字组合表面上就是三个数字排列但背后是穷举法的雏形第2题奖金提成看起来是分段计算实际上就是真实业务里最常见的“分段计费模型”。这种“小题目带出大思想”的设计是很多现代刷题网站都做不到的。所以我的建议是哪怕你已经能写爬虫、能调库回头刷一遍前10题也不亏。很多基础不牢的人往往就是栽在“列表复制到底复制了什么”这种问题上。1.2 前10题考察点速查在真正动手之前先花一分钟看一下这10道题的分布心里有个谱题号题目场景核心知识点难度1数字组合循环嵌套、排列穷举★2奖金提成分支判断、分段计算★★3完全平方数数学建模、枚举法★★★4日期判断列表、闰年规则、切片求和★★5三个整数排序比较交换、排序启蒙★6斐波那契数列迭代、递归与性能★★7列表复制引用、浅拷贝与深拷贝★★★8九九乘法表嵌套循环、格式化输出★★9暂停输出time模块、程序挂起★10格式化时间time模块、strftime格式符★★从这张表能看出来前10题不是随便排的。第1题让你感受循环嵌套第2、3题开始加入分支和数学思维第4、5题进入列表和排序的范畴第6、7题开始考察“稍微绕一点”的算法和内存模型最后8~10题又回到输出格式和模块使用。难度是波浪式上升的不是一下子把你劝退。我当时带新人刷这套题时会要求大家每道题至少写两遍第一遍照着思路写第二遍关上答案自己从头写一遍写不出来就去看报错再看答案。前10题通过这种方式打底后面的题会顺手很多。2. 做题之前环境、读题与调试三板斧2.1 环境准备好少踩一半坑既然是零基础向的题目环境问题确实是第一道坎。我的建议很简单去Python官网下载最新的稳定版安装时一定勾选“Add Python to PATH”这样你才能在终端里直接用python命令。装完之后打开终端输入下面这行python --version如果能看到类似Python 3.10.x的输出说明环境没问题。编辑器方面不想折腾就用IDLE想舒服一点就装VS Code然后装一个Python插件配置好解释器路径就行。不过前10题涉及的代码量很小你用记事本写、用命令行跑也完全够用不必在工具上花太多时间。顺便说一句别在这时候纠结“用Python 2还是Python 3”。现在的新代码一律用Python 3老题里有些print写法是Python 2的残留比如print后面不跟括号这种写法在新版本里直接报错。你只要看到代码里有print(...)就是Python 3风格放心用。2.2 拿到题目先别敲代码先做这三步很多人刷题的习惯是“看到题目就开写”然后卡住再从头看题目。我的习惯相反拿到题目后先手算一个例子再把步骤写成伪代码最后才翻译成Python。比如第2题奖金提成你完全可以先拿笔算一遍“利润25万时奖金多少”算的过程中你会自然想一想分段边界在哪里。这个过程不是在浪费时间而是在帮你“建模”。伪代码也不用写得很规范自己能看懂就行。第1题如果写伪代码大概就是个位、十位、百位都从1到4取数三个位上的数字不能重复拼成一个三位数并打印等伪代码写清楚再翻译成Python基本不会有大方向上的错误。我见过太多人写第1题时在循环条件里纠结半天就是因为跳过了“先想”这一步。2.3 报错不可怕可怕的是不看报错新手看到一个红字Traceback容易慌其实报错信息已经是程序在告诉你“我哪里出问题了”。比如NameError: name x is not defined意思是解释器在内存里找不到名叫x的变量。你第一反应应该是“我是不是拼错了变量名”“是不是忘了赋值”而不是重新跑一遍。另一种特别常见的是缩进错误IndentationError: expected an indented block这种基本都是if、for、def这些语句的下一行没有缩进或者缩进不一致。Python用缩进划分代码块所以同一层级的代码缩进必须统一我建议全部用4个空格。调试时我有个笨办法最实用print大法。不确定某个变量是什么值直接打印不确定某段代码有没有执行在关键位置加print(到这里了)。等逻辑通了再把print删掉。尤其第4题日期判断很多人算错天数就是因为没打印中间结果直接出结论。3. 实战解析程序1~10逐题拆解3.1 第1~3题从穷举到建模第1题数字组合题目描述是有1、2、3、4四个数字能组成多少个互不相同且无重复数字的三位数分别是多少这题几乎不需要任何高深技巧就是三重循环。百位从1到4取十位从1到4取个位从1到4取只要三个数互不相同就拼成一个三位数。count 0 results [] for i in range(1, 5): # 百位 for j in range(1, 5): # 十位 for k in range(1, 5): # 个位 if i ! j and j ! k and i ! k: results.append(i * 100 j * 10 k) count 1 print(f共 {count} 个) print(results)输出结果一共24个从123开始到432结束。这里你需要注意三个循环的边界range(1, 5)生成的是1、2、3、4这四个数不包含5。很多人写成range(1, 4)那就只剩1、2、3了结果就错了。如果你已经把这段代码跑通了我建议你再想想如果从1到9共9个数字中取4个不重复数字组成四位数用4重循环会是什么样能不能用itertools.permutations一步搞定这些都是从第1题延伸出来的思考题。第2题奖金提成这题是经典的分段计费模型。企业发放奖金利润低于等于10万元的部分按10%提成10万到20万之间的部分按7.5%20万到40万之间按5%40万到60万之间按3%60万到100万之间按1.5%超过100万的部分按1%。最直观的做法就是if-elif按区间判断。注意单位统一下面代码里我直接用“万元”作单位profit float(input(请输入当月利润万元)) if profit 10: bonus profit * 0.1 elif profit 20: bonus 10 * 0.1 (profit - 10) * 0.075 elif profit 40: bonus 10 * 0.1 10 * 0.075 (profit - 20) * 0.05 elif profit 60: bonus 10 * 0.1 10 * 0.075 20 * 0.05 (profit - 40) * 0.03 elif profit 100: bonus 10 * 0.1 10 * 0.075 20 * 0.05 20 * 0.03 (profit - 60) * 0.015 else: bonus 10 * 0.1 10 * 0.075 20 * 0.05 20 * 0.03 40 * 0.015 (profit - 100) * 0.01 print(f应发奖金{bonus:.2f} 万元)这版代码虽然长但逻辑透明。实际工作里这类分段计费如果区间很多用if-elif写起来会非常痛苦。我在这里提供一个更“职业”一点的写法用两个列表把阶梯和对应提成比例存起来然后从高档位往低档位“剥洋葱”thresholds [100, 60, 40, 20, 10, 0] rates [0.01, 0.015, 0.03, 0.05, 0.075, 0.1] profit float(input(请输入当月利润万元)) bonus 0 for i in range(len(thresholds)): if profit thresholds[i]: bonus (profit - thresholds[i]) * rates[i] profit thresholds[i] print(f应发奖金{bonus:.2f} 万元)这段代码的思路是如果当前利润超过某个档位的起始值就把超出部分按该档位的比例算奖金然后把利润“压”到这一档的起始值继续往下一档算。当利润等于25万时先算20万到40万这档的5万部分再算10万到20万这档最后算10万以下部分最终得到2.0万元和手算结果一致。第3题完全平方数题目描述一个整数它加上100后是一个完全平方数再加上168又是一个完全平方数请问该数是多少这题在经典题里属于“数学味”比较重的一道。最稳妥的思路是暴力枚举。问题是枚举范围怎么定题目没有给所以我们要自己估算一个合理区间。比如从-100枚举到10000虽然不够严谨但对于这道题足够覆盖答案了。import math def is_square(num): if num 0: return False root math.isqrt(num) return root * root num results [] for x in range(-100, 10000): if is_square(x 100) and is_square(x 100 168): results.append(x) print(results)注意我用了math.isqrt而不是int(math.sqrt())。原因是isqrt是纯整数运算不会出现浮点数精度误差在判断完全平方数时更可靠。这段代码的输出是[-99, 21, 261, 1581]也就是说满足条件的整数有4个。如果你想更优雅可以设两个变量m和n令x100n²x268m²那么m²-n²168。进一步得到(mn)(m-n)168枚举168的因数对再判断两个因数是否同奇偶就能直接解出来不用循环上万次。这就是数学建模的价值。我建议你暴力法跑通之后再往这个方向想一想能体会到“程序跑得快不全靠硬件”。3.2 第4~5题边界条件与排序思想第4题日期判断输入某年某月某日判断这一天是这一年的第几天。这题的关键是闰年规则能被400整除的年份是闰年或者能被4整除但不能被100整除的年份是闰年。这里特别容易出错的是把“能被4整除”当成唯一条件那样1900年就会被误判为闰年。闰年影响的是2月的天数所以我会先把12个月的天数存进列表闰年再把索引为1的元素改成29。year int(input(请输入年份)) month int(input(请输入月份)) day int(input(请输入日期)) days_in_month [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] if (year % 400 0) or (year % 4 0 and year % 100 ! 0): days_in_month[1] 29 total sum(days_in_month[:month - 1]) day print(f{year}年{month}月{day}日是这一年的第 {total} 天)这里有一个特别容易踩的坑列表索引从0开始days_in_month[0]代表1月。所以计算“之前月份天数总和”时切片一定要写到month - 1。比如输入3月10日应该sum(days_in_month[:2])即1月加2月再置day。如果你写成days_in_month[:month]就会把3月的天数也算进去结果会多出31天。这种边界问题靠背是记不住的最好的办法就是拿几个日期手算对照。测试时建议用这三组数据2000年2月29日闰年、1900年2月28日不是闰年、2024年12月31日闰年且跨年。只要这三个都能算出正确答案这题基本就稳了。第5题三个整数排序输入三个整数x、y、z请把这三个数按从小到大的顺序输出。这题如果直接调sorted一秒钟就写完了但那就失去了练习的意义。经典做法是用三次比较交换x int(input(请输入x)) y int(input(请输入y)) z int(input(请输入z)) if x y: x, y y, x if x z: x, z z, x if y z: y, z z, y print(x, y, z)思路是第一次保证x是x和y里较小的一个第二次保证x是三个数里最小的一个第三次处理y和z的大小关系。三个if缺一不可而且必须是独立if不能写成if-elif否则会漏掉比较。变量交换写法x, y y, x是Python特有的非常方便。你要是用C语言写得引入临时变量temp。理解了这段代码其实你已经接触到了最朴素的排序思想——每一轮比较把最小的数“冒泡”到最前面。后续题库里如果出现“排序10个数”之类的题核心思路和这个是一脉相承的。3.3 第6~7题递推、递归与对象引用第6题斐波那契数列斐波那契数列的规律是前两项是0和1也有版本从1和1开始从第三项开始每一项都等于前两项之和。这个规律用迭代写非常简单n int(input(你想输出前几项)) a, b 0, 1 fib [] for _ in range(n): fib.append(a) a, b b, a b print(fib)这里最值得讲的是a, b b, a b这条语句。很多人刚学时以为它是先算b再算ab其实Python会先把右边的b和ab都计算出来然后同时赋值给a和b。所以即使a已经被更新成b计算ab时用的还是旧a。这就是为什么这个写法能正确推进数列。如果你输入n10输出是[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]还有一种写法是递归def fib_recursive(n): if n 1: return n return fib_recursive(n - 1) fib_recursive(n - 2)递归版代码简洁但我建议你实测一下。用fib_recursive(35)去跑你会发现明显卡顿而迭代版几乎是瞬间出结果。原因是递归版会重复计算大量子问题时间复杂度接近O(2^n)迭代版只用一重循环复杂度只有O(n)。这就是算法意识最早的启蒙。第7题列表复制题目描述很简单将一个列表的数据复制到另一个列表中。但越简单的题越容易暴露问题。新手最容易写出来的“错误答案”是这样的a [1, 2, 3, 4, 5] b a # 这只是复制了引用 b.append(6) print(a) # [1, 2, 3, 4, 5, 6] a也被改了 print(b) # [1, 2, 3, 4, 5, 6]原因在于Python里变量名存的是对象的引用b a并没有创建一个新列表只是让b和a指向同一个列表对象。你通过b去修改列表a看到的内容当然也会变。这就好比你给房子多配了一把钥匙谁拿钥匙进来重新刷了墙原房主看到的也是新墙。想真正复制可以用切片、list()构造或copy模块a [1, 2, 3, 4, 5] b a[:] # 方式一切片复制 c list(a) # 方式二构造新列表 import copy d copy.copy(a) # 方式三copy模块浅拷贝 b.append(6) c.append(7) d.append(8) print(a) # 只有 a 保持 [1, 2, 3, 4, 5]但这题到“浅拷贝”还没完。如果列表内部还有可变对象比如嵌套列表那么a[:]复制出来的新列表内层列表仍然和原列表共享。想彻底复制所有层需要copy.deepcopy。这个坑在数据处理场景里特别常见你备份了一份原始数据结果改着改着发现原始数据也变了多半就是浅拷贝导致的。3.4 第8~10题循环、格式化与时间模块第8题九九乘法表输出九九乘法表这题考察的是嵌套循环和格式化输出。标准版是下三角for i in range(1, 10): for j in range(1, i 1): print(f{j} * {i} {i * j:2}, end ) print()这里的关键有两点。第一内层循环的range(1, i 1)让列数随着行数增加所以输出是三角形而不是矩形。第二end 表示这一行每次打印完不换行而是用4个空格分隔等内层循环结束再用一个空的print()换行。你可能会问f{i * j:2}里的:2是什么它的意思是让结果右对齐并至少占2个字符宽度。这样1 * 1 1里的1前面会有一个空格看起来整体更整齐。如果没有这个对齐输出会歪歪扭扭。如果你看腻了下三角可以自己改成上三角把内层循环改成for j in range(i, 10)。一行代码的差别输出的形状完全不一样。这种“改条件看效果”的玩法特别适合理解循环边界。第9题暂停输出题目要求是暂停一秒再输出其实核心就一个知识点time.sleep()。import time for i in range(1, 6): print(f第 {i} 秒) time.sleep(1) print(结束)sleep的参数单位是秒想暂停0.5秒就写time.sleep(0.5)。这段代码跑起来会明显感觉到“卡”了5秒但这不是程序卡死是主动挂起。有一点我想提醒你在PyCharm这类IDE里运行print默认可能带有输出缓冲让人觉得“为什么程序停住了还没输出”。如果遇到这种情况可以在print里加一个flushTrue参数强制刷新输出缓冲区print(f第 {i} 秒, flushTrue)第9题虽然简单但sleep是爬虫限速、定时任务、循环动画这些场景的基础操作。你以后写爬虫时为了不把对方服务器请求崩经常会在两次请求之间加一个随机延迟本质上就是sleep的变体。第10题格式化当前时间经典描述是暂停一秒后格式化输出当前时间。这题和第9题是搭档主要考time模块里的localtime和strftime。import time for i in range(5): now time.localtime() print(time.strftime(%Y-%m-%d %H:%M:%S, now)) time.sleep(1)time.localtime()返回一个包含当前年月日时分秒的结构化时间对象strftime负责把它转成字符串。这里的格式符可以自由组合占位符含义示例%Y四位年份2025%m两位月份不足补003%d两位日期不足补008%H24小时制小时14%M分钟05%S秒09比如你想输出“2025/03/08 14:05:09”就把格式串写成%Y/%m/%d %H:%M:%S。很多初学者会把%m和%d搞混其实你只要记住%m是month%d是day就行了。另外strftime是“把时间对象格式化成人能看懂的字符串”反方向的strptime是“把字符串解析成时间对象”这两个函数在以后处理日志、处理数据文件时会反复用到值得提前混个脸熟。4. 常见问题与排查技巧实录4.1 高频报错速查表前10题刷下来你大概率会遇到下面这些报错。我把它们整理成一张速查表下次报错直接对照看报错信息含义常见原因解决办法IndentationError缩进错误if/for后没缩进或缩进不一致统一用4个空格缩进NameError: name ... is not defined变量未定义变量名拼错、没赋值就使用顺着代码往前查变量定义TypeError: int object is not iterable对整数做了遍历把for i in range(5)写成了for i in 5被遍历对象必须是可迭代类型IndexError: list index out of range列表索引越界访问了不存在的索引比如列表长度是12却访问[12]特别检查“索引是否比长度小1”TypeError: unsupported operand type(s)类型不支持运算字符串和数字直接做加法比如score: 95用int()转换或使用f-string这些报错本身不可怕关键是看到之后不要慌。我会建议新手把报错信息复制到搜索引擎里搜但更重要的是看懂Traceback最后一行那行才是“真正的死因”。4.2 比报错更隐蔽的逻辑坑语法报错有迹可循逻辑错误才是真正容易让人抓狂的。前10题里有几个典型的逻辑坑。第一个是第2题奖金提成的判断顺序。如果你把if profit 10这层放到了最后那么任何大于10的利润都会被前面的elif拦截导致计算错误。判断分段的顺序必须从小到大或者用列表法从大到小剥不能乱。第二个是第4题的闰年判断。很多人会写if year % 4 0然后就认为所有能被4整除的都是闰年。实际上1900年能被4整除但不是闰年因为还要被100整除且不被400整除。判断条件的完整写法是(year % 400 0) or (year % 4 0 and year % 100 ! 0)。第三个是第7题的列表共享。这个前面已经详细说过一句话总结如果你发现“我只是想改备份怎么原数据也变了”先检查是不是用了浅拷贝。第四个坑藏在第6题。如果你把a, b b, a b拆成a b和b a b两行分别写结果就完全不对了。Python的并行赋值和普通语句的执行顺序不一样这个知识点值得单独记在小本子上。4.3 我常用的三个调试方法我调试代码时基本不依赖高级工具三个方法就能覆盖大多数场景。第一个是print中间变量。比如第4题判断日期我会在算出total之前先print(days_in_month)看看闰年判断有没有生效print(sum(days_in_month[:month - 1]))看看累加天数有没有问题。看到中间值问题往往一眼就能定位。第二个是缩小数据范围。前10题里的循环范围都不大遇到难以理解的问题时可以把range(10000)改成range(20)把输入数据改成很小的数然后手算一遍对照输出。比如第3题完全平方数你完全可以先把范围缩小到0到100看看自己写的is_square是不是可靠。第三个是“故意制造错误”。这个听起来有点反直觉但我确实经常这么干如果我不确定某段代码会不会执行我就在里面写print(这段代码进来了)如果没打印出来说明if条件没满足或者循环没进去。这比盯着代码看要有用得多。5. 从这10道题延伸出去的方向刷完前10题很多人的感觉是“好像都会了但又好像什么都没抓住”。这是因为前10题本身只是引子它们后面的延伸方向才是宝藏。第1题的排列组合穷举可以延伸去学itertools库以后写密码字典生成、排列组合测试都会用到。第2题的分段计费模型往小里说是个数学题往大里说就是阶梯电价、个税计算、快递运费这类系统的核心逻辑。你理解了if-elif版和列表版之后再去看业务系统里的计费模块会觉得很亲切。第4题的日期判断延伸出去就是datetime模块处理时间序列、日志分析、定时任务都离不开它。第6题的斐波那契数列是递归和动态规划的入门钥匙第7题的深浅拷贝在数据处理、配置备份时特别重要。第10题的strftime格式化看起来只是输出一行时间实际上是所有日志系统的必备知识也是爬虫里常见的时间戳处理基础。所以我的建议是刷完前10题别急着往后赶。把第2题用列表法重写一遍把第6题改成“输入项数输出斐波那契数”把第7题写一个嵌套列表并用deepcopy复制。这些改动都不大但每改一次知识就从“眼睛会了”变成“手也会了”。说实话这套前10题我带着不止一批新人刷过最快的人半天刷完最慢的人磨了三天。刷得快不代表掌握得好因为后面很多题目会反复调用这一阶段的知识。比如后面讲到函数时可能会让你把斐波那契封装成函数讲到类和对象时可能让你把日期判断封装成日期类讲到文件操作时可能让你把乘法表输出到文件。这些都是在“炒冷饭”但你如果前10题是真正敲过、改过、踩过坑的后面这些题就是在复习老朋友如果前10题只是抄了一遍答案后面就会越来越吃力。我个人最大的体会是学编程最忌讳“进度焦虑”。你不需要一天刷10题你只需要把1题真正吃透。所谓吃透就是关上答案能自己写出来改一个条件还能写出变体过两周再回头看还能讲清楚思路。如果前10题里每一题都能达到这个标准那你在Python基础上花的这几个小时绝对比刷完100道题却全忘光要值钱得多。下一步别贪多从第11题开始继续用这一篇里聊到的思路先想再写跑通后改改完再总结。这套方法能陪你走完整整100题。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价