☰
PTA Python第三章3-1至3-22题解:分支循环字符串列表全攻略
2026/10/16 7:41:33 网站建设 项目流程

1. 从题库到能力:为什么第三章值得反复刷

Python 基础语法里,第三章通常是从“会写一行代码”跨到“能独立完成一个小逻辑”的分水岭。很多初学者在第二章还能靠记忆应付过去,到了第三章就开始卡壳——循环嵌套写不对、列表索引越界、字符串切片搞混、输出格式差一个空格就全错。这不是智力问题,而是编程思维还没有从“翻译题目”切换到“拆解问题”。

PTA 平台的 Python 编程题第三章(3-1 到 3-22)恰好覆盖了这几个最容易翻车的知识点:分支结构、循环控制、字符串处理、列表基础操作、简单算法入门。题目本身不难,但每道题都在逼你养成一个习惯——先想清楚输入输出长什么样,再动手写逻辑。这个习惯一旦养成,后面第四章的函数、第五章的文件操作都会顺很多。

这篇文章适合两类人:一类是正在上 Python 课程、被 PTA 作业卡住的学生,另一类是自学 Python 但发现自己“看得懂代码、写不出程序”的初学者。我会把 3-1 到 3-22 这 22 道题按知识点分组拆解,每道题给出思路分析、参考代码、常见错误和避坑技巧。代码全部基于 Python 3.x,可以直接在 PTA 上提交验证。

提示:PTA 的判题系统对输出格式极其敏感,多一个空格、少一个换行都会判错。建议每道题先在本地用print(repr(输出))检查一遍再提交。

2. 第三章知识地图与题目分组

2.1 这 22 道题到底在考什么

把 3-1 到 3-22 的题目快速过一遍,会发现它们并不是随机排列的,而是按照知识点递进设计的。大致可以分成四个梯队:

梯队题号范围核心考点难度感受
基础分支3-1 ~ 3-5if-elif-else、条件表达式、闰年判断入门
循环入门3-6 ~ 3-11for/while、range、累加累乘、数列求和简单
字符串与列表3-12 ~ 3-17切片、查找、替换、列表增删改查中等
综合应用3-18 ~ 3-22嵌套循环、简单算法、格式化输出偏难

这个分组不是官方给的,是我自己刷完之后按“卡壳频率”重新整理的。你会发现,卡壳最多的不是难题,而是那些看起来简单但输出格式刁钻的题。比如 3-5 的闰年判断,逻辑三行就写完了,但很多人因为没处理“整百年份必须能被 400 整除”这个边界条件而反复提交失败。

2.2 刷题前必须搞清楚的三个概念

在进入具体题解之前,有三个概念必须先说清楚,否则后面每道题都会踩坑。

第一个是range()的边界。range(1, 5)生成的是 1、2、3、4,不包含 5。这个“左闭右开”的规则在循环里反复出现,比如“输出 1 到 n 的所有整数”要写range(1, n+1),少写一个+1就会漏掉最后一个数。我见过太多人在 3-8 这种累加题上因为这个问题卡了半小时。

第二个是字符串的不可变性。Python 里字符串一旦创建就不能修改,所有“修改”操作实际上都是返回一个新字符串。比如s.replace('a', 'b')不会改变s本身,必须用s = s.replace('a', 'b')才能生效。3-14 和 3-15 这两道字符串题,很多人就是在这里翻车的。

第三个是列表索引从 0 开始。第 1 个元素是lst[0],第 n 个元素是lst[n-1]。负索引lst[-1]表示最后一个元素,这个特性在处理“取末尾字符”时很好用,但初学者容易搞混正负索引的边界。

注意:PTA 上有些题目会给出“输入保证合法”的说明,但这不代表你可以忽略边界情况。比如输入可能为空、可能只有一行、可能末尾有空格,这些都要在本地测试时考虑到。

3. 分支结构题组(3-1 ~ 3-5)逐题拆解

3.1 3-1 到 3-3:条件判断的基本功

这三道题是分支结构的入门,核心就一件事——把题目里的自然语言条件翻译成 Python 的布尔表达式。

3-1 通常是“判断一个数是正数、负数还是零”。看起来简单,但要注意题目要求的输出格式。有的题目要求输出 “positive”、“negative”、“zero”,有的要求输出中文,还有的要求输出 “+” “-” “0”。一定要逐字对照题目给的输出样例,不要凭感觉写。

参考代码框架:

n = int(input()) if n > 0: print("positive") elif n < 0: print("negative") else: print("zero")

3-2 一般是“判断奇偶数”或者“判断能否被某数整除”。这里有个小技巧:判断偶数可以用n % 2 == 0,也可以用n & 1 == 0(位运算),但后者可读性差,不建议在初学阶段用。代码是写给人看的,其次才是给机器执行的。

3-3 开始引入多条件判断,比如“根据成绩输出等级”。这种题的关键是条件顺序。如果你先判断score >= 60输出“及格”,再判断score >= 90输出“优秀”,那 95 分也会先命中“及格”。正确的做法是从高到低判断,或者用elif确保互斥。

score = int(input()) if score >= 90: print("优秀") elif score >= 80: print("良好") elif score >= 60: print("及格") else: print("不及格")

实操心得:写多分支判断时,先在纸上画出数轴,标出每个分支覆盖的区间,确认没有重叠和遗漏再写代码。这个习惯能帮你省下大量调试时间。

3.2 3-4 到 3-5:闰年判断与边界条件

3-4 和 3-5 通常涉及闰年判断或者类似的“多条件组合”问题。闰年的规则是:能被 4 整除但不能被 100 整除,或者能被 400 整除。翻译成 Python:

year = int(input()) if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0): print("yes") else: print("no")

这道题的坑在于运算符优先级。and的优先级高于or,所以a and b or c等价于(a and b) or c。如果你写成year % 4 == 0 and year % 100 != 0 or year % 400 == 0,逻辑是对的,但可读性差。加括号不丢人,丢人的是逻辑写错了还找不到原因。

另一个常见错误是忘记处理“整百年份”。比如 1900 年能被 4 整除,也能被 100 整除,但不能被 400 整除,所以不是闰年。很多人只写了year % 4 == 0就提交,结果在 1900 这个测试点上挂了。

注意:PTA 的测试数据通常包含边界值,比如 2000 年(闰年)、1900 年(平年)、2024 年(闰年)。本地测试时至少要把这三个年份都跑一遍。

4. 循环结构题组(3-6 ~ 3-11)核心套路

4.1 3-6 到 3-8:累加、累乘与数列求和

这三道题是循环的入门,核心套路就一个——初始化累加器,然后在循环里更新它。

3-6 通常是“求 1 到 n 的和”。代码很简单:

n = int(input()) total = 0 for i in range(1, n + 1): total += i print(total)

但这里有个隐藏考点:n 可能很大。如果 n 是 10^9,用循环累加会超时。不过 PTA 第三章的题目通常不会卡这个,n 一般在 100 以内。但你要有这个意识——循环的时间复杂度是 O(n),能用公式的地方尽量用公式。1 到 n 的和可以用n * (n + 1) // 2直接算,O(1) 搞定。

3-7 一般是“求 n 的阶乘”。这里要注意total的初始值必须是 1,不是 0。我见过有人写total = 0然后total *= i,结果永远是 0。累加初始化为 0,累乘初始化为 1,这是铁律。

3-8 开始引入数列求和,比如“求 1 + 1/2 + 1/3 + ... + 1/n”。这里要注意浮点数精度。Python 的float是双精度,一般够用,但如果题目要求保留多位小数,要用格式化输出:

n = int(input()) total = 0.0 for i in range(1, n + 1): total += 1 / i print(f"{total:.6f}")

实操心得:PTA 上浮点数输出通常要求保留 6 位小数,用 f-string 的:.6f最方便。不要用round(),因为round()返回的是数值,输出时可能不会补零。

4.2 3-9 到 3-11:循环控制与嵌套入门

3-9 和 3-10 通常涉及break和continue的使用。比如“找到第一个满足条件的数”用break,“跳过某些数”用continue。这里的关键是理解循环的执行流程,建议在纸上画流程图,标出break和continue跳转的位置。

3-11 开始引入简单的嵌套循环,比如“输出乘法表”或者“打印三角形”。嵌套循环的难点在于内外层变量的关系。以打印直角三角形为例:

n = int(input()) for i in range(1, n + 1): for j in range(i): print("*", end="") print()

外层i控制行数,内层j控制每行的星号数。print()在內层循环结束后执行,负责换行。很多人忘记写最后的print(),导致所有输出挤在一行。

注意:print()默认换行,print("*", end="")表示不换行。在嵌套循环里,内层用end="",外层用默认换行,这个模式要记牢。

5. 字符串与列表题组(3-12 ~ 3-17)实战技巧

5.1 3-12 到 3-14:字符串切片与查找

字符串是 Python 里最常用的数据类型之一,第三章的字符串题主要考三个操作:切片、查找、替换。

3-12 通常是“字符串反转”或者“取子串”。Python 里字符串反转用切片最方便:s[::-1]。这个语法的含义是“从头到尾,步长为 -1”,也就是倒序。取子串用s[start:end],注意end不包含在内。

3-13 一般是“查找字符位置”。可以用s.find(ch),返回第一次出现的索引,找不到返回 -1。也可以用s.index(ch),找不到会抛异常。在 PTA 上建议用find(),因为不需要处理异常。

3-14 开始涉及替换和统计。比如“把字符串里的所有空格替换成逗号”:

s = input() s = s.replace(" ", ",") print(s)

这里再次强调:replace()返回新字符串,必须重新赋值。如果你写s.replace(" ", ",")然后直接print(s),输出的还是原字符串。

实操心得:处理字符串时,先用print(repr(s))看一下字符串的真实内容,确认有没有隐藏的空格或换行符。PTA 的输入有时会带末尾空格,直接比较会出错。

5.2 3-15 到 3-17:列表基础操作

列表题的核心是增删改查四个操作:

操作方法说明
增append(x)末尾添加元素
删remove(x)删除第一个值为 x 的元素
改lst[i] = x修改指定索引的元素
查x in lst判断元素是否存在

3-15 通常是“列表去重”或者“列表排序”。去重可以用set(),但set是无序的,如果题目要求保持原顺序,需要手动遍历:

lst = list(map(int, input().split())) result = [] for x in lst: if x not in result: result.append(x) print(result)

3-16 和 3-17 开始涉及列表的遍历和条件筛选。比如“输出所有大于平均值的数”。这种题分两步:先求平均值,再遍历筛选。

lst = list(map(int, input().split())) avg = sum(lst) / len(lst) for x in lst: if x > avg: print(x, end=" ")

注意:input().split()默认按空格分割,返回字符串列表。如果题目输入的是整数,要用map(int, ...)转换。如果输入在一行里用逗号分隔,要用split(",")。

6. 综合应用题组(3-18 ~ 3-22)思路拆解

6.1 3-18 到 3-20:嵌套循环与简单算法

这三道题开始把前面的知识点组合起来,比如“打印菱形”、“求素数”、“进制转换”。

以“打印菱形”为例,思路是把它拆成上半部分和下半部分。上半部分是一个正三角形,下半部分是一个倒三角形。关键是找到每行的空格数和星号数与行号的关系:

n = int(input()) for i in range(1, n + 1): print(" " * (n - i) + "*" * (2 * i - 1)) for i in range(n - 1, 0, -1): print(" " * (n - i) + "*" * (2 * i - 1))

“求素数”的经典写法是试除法,从 2 试到sqrt(n):

n = int(input()) is_prime = True if n < 2: is_prime = False else: for i in range(2, int(n ** 0.5) + 1): if n % i == 0: is_prime = False break print("yes" if is_prime else "no")

实操心得:判断素数时,循环上界用int(n ** 0.5) + 1比n快很多。虽然第三章的数据规模不大,但养成这个习惯对后面做算法题有帮助。

6.2 3-21 到 3-22:格式化输出与综合应用

最后两道题通常是综合应用,涉及格式化输出和多个知识点的组合。比如“输出成绩表”或者“统计字符类型”。

格式化输出推荐用 f-string:

name = "张三" score = 95.5 print(f"{name}: {score:.1f}")

统计字符类型是经典题:统计一串字符里字母、数字、空格、其他字符的个数。

s = input() letters = digits = spaces = others = 0 for ch in s: if ch.isalpha(): letters += 1 elif ch.isdigit(): digits += 1 elif ch.isspace(): spaces += 1 else: others += 1 print(letters, digits, spaces, others)

这道题的坑在于输入可能包含多行。如果题目说“输入一行字符串”,用input()就够了;如果说“输入多行”,需要用sys.stdin.read()或者循环读取。

注意:isalpha()判断的是 Unicode 字母,中文也会返回 True。如果题目只要求统计英文字母,需要用ch.isascii() and ch.isalpha()。

7. 常见问题与排查技巧实录

7.1 PTA 判题常见错误速查表

错误提示可能原因解决方法
答案错误输出格式不对用repr()检查输出,对照样例逐字比较
运行超时循环次数过多检查是否有死循环,考虑用公式替代循环
非零返回程序抛异常检查输入转换、索引越界、除零
段错误递归过深或内存问题第三章一般不涉及,检查是否有无限递归
格式错误多余空格或换行检查print的end参数和末尾换行

7.2 我踩过的三个坑

第一个坑:input()读取多行。有些题目说“输入若干行,每行一个整数”,但没给行数。这时候不能只调一次input(),要用sys.stdin或者try-except:

import sys for line in sys.stdin: n = int(line.strip()) # 处理 n

第二个坑:浮点数比较。PTA 有些题要求“判断两个浮点数是否相等”,直接用==会因为精度问题出错。正确做法是判断差值是否小于一个极小值:

if abs(a - b) < 1e-6: print("equal")

第三个坑:列表越界。在循环里访问lst[i+1]时,如果i到了最后一个索引,就会越界。解决办法是循环范围改成range(len(lst) - 1),或者用try-except捕获。

实操心得:每道题提交前,至少用三组数据测试——最小输入、最大输入、边界输入。比如 n=0、n=1、n=100。这三组能过,基本就没问题了。

7.3 调试技巧:打印中间变量

PTA 上看不到运行过程,所以本地调试很重要。在关键位置加print输出中间变量,确认逻辑是否正确:

n = int(input()) total = 0 for i in range(1, n + 1): total += i print(f"i={i}, total={total}") # 调试用,提交前删掉 print(total)

提交前记得把调试语句删掉,否则会输出多余内容导致答案错误。

8. 从第三章到后续章节的衔接建议

第三章刷完之后,你会对 Python 的基本控制流有一个完整的认识。接下来第四章通常是函数,第五章是文件操作,第六章是面向对象。这三章的共同特点是代码量开始变大,所以第三章养成的习惯会直接影响后面的学习效率。

我的建议是:第三章的 22 道题至少刷两遍。第一遍按题号顺序做,遇到不会的看题解;第二遍打乱顺序做,只看题目不看题解,逼自己独立完成。第二遍如果能在 40 分钟内做完 22 道题,说明第三章的知识点已经内化了。

另外,PTA 上的题目只是手段,不是目的。真正重要的是把每道题的思路用自己的话讲一遍。如果你能对着空气把“闰年判断”的逻辑讲清楚,把“素数判断”的循环边界说明白,那你就真的掌握了。这比刷一百道题都有用。

最后分享一个小技巧:建一个自己的“错题本”,把每次提交失败的原因记下来。比如“3-5 忘记处理 1900”、“3-14 忘记重新赋值字符串”。考前翻一遍,比重新刷题效率高得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询