ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Python期末复习全攻略:语法体检与易错点详解

Python期末复习全攻略:语法体检与易错点详解

简介:面向K12阶段Python初学者的期末复习要点文档,以清晰条目梳理期末高频考点,包含输入输出、字符串排序去重、列表逆序与去重、自定义sort排序、桶排序、二分查找、模块化设计、异常处理及面向对象核心概念,可作为考前快速回顾与查漏补缺的随身清单。资源包为单个docx格式文档,约865KB,共1个文件,适合打印或电脑阅读,内容紧凑无需额外解压繁琐操作,该资料上线后已有439人学习,适合正在备战Python期末考试的K12学生及入门爱好者。除了系统归纳基础语法,还额外整理了一系列易错点与典型代码示例,例如list.sort()原地排序返回None、浅拷贝与深拷贝区别、集合升序去重特性等,能帮助理解本质并降低考试踩坑概率,整体覆盖选择、填空与编程题常考角度,是一份能直接对照练习的实用复习资料。

1. Python 期末复习到底在复习什么?一场给 K12 新手的“语法体检”

K12 阶段的 Python 期末复习,最怕的不是题目难,而是很多同学把 Python 当黑匣子——代码看着熟,一运行就翻车。期末考的本质,其实是给这段学习做一次“语法体检”:数据怎么进、存进哪种容器、最后怎么出,每一步都有固定规则。用收拾书包来打比方,input() 是往书包里塞东西,列表和字典是不同隔层,print() 是把书拿出来展示。如果“进、存、出”这条主线没理顺,后面所有代码都会跟着歪。这篇文章不谈玄学,专门把期末常考的概念掰开揉碎,帮你建立一眼看穿的认知。

2. 输入输出这条主线:期末卷上的“分数搬运工”

2.1 连续输入:一行代码背后的三个小机关

先记住一句话:input() 永远只负责“读一整行字符串”,它不关心你输入的是几个数。K12 题目里经常出现“一行给三个整数”“一行给若干名字”,如果你老实写三行 input(),代码又臭又长,还容易漏读。所以卷子上高频出现这种写法:

a, b, c = map(int, input().split())

这段代码能拆成三个小机关:

  • input()读进来的是字符串,例如"1 2 3";
  • .split()默认按空格把字符串切成列表,得到["1", "2", "3"];
  • map(int, 列表)把每个字符串转成整数,再依次赋给 a、b、c。

很多同学误以为 input() 能直接返回“三个数”,其实它返回的是一整行文本。split() 像一把餐刀,把一串文字从空格处切开;map() 像一台翻译器,把切好的文字翻译成目标类型。如果直接用A, B = input().split(),得到的是两个字符串,而不是数字。题目说要整数时,忘了 map,后面做加法就会得到字符串拼接而不是数值求和。

那么什么时候用split(',')?看输入分隔符。输入"A同学,B同学,C同学"就必须写成.split(','),否则切不开。所以复习时要主动问自己:我读的是空格分隔还是逗号分隔?这是每年都有不少人踩的坑。

更进一步,如果题目要在一行里读“一整列数字”,可以用:

num_list = list(map(int, input().split()))

这行代码的意思是把分解、转换后的结果装进一个列表,作为后续排序、统计的原料。可以说,input().split().map()是期末输入题的标准三件套,背住它的执行顺序,就能看懂一切像天书一样的读入代码。

2.2 print 不是“一键输出”:五个参数决定它怎么干活

print 是每个 Python 新手学的第一个函数,但期末考根本不考“print 能打印什么”,而是考“print 到底按什么规则打印”。完整格式是:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

参数逐个说:

  • objects:要输出的对象,可以放多个,用逗号隔开;
  • sep:多个对象之间的分隔符,默认空格;
  • end:整个输出以什么结尾,默认换行;
  • file:输出到哪里,默认屏幕;
  • flush:是否立即刷新缓冲区,默认 False。

看了这个签名,很多“诡异输出”就解释得通了。比如你想输出“A同学的编号-2024”,且结尾不换行:

print("A同学", 2024, sep="-", end="!")

输出就是A同学-2024!。如果 sep 不写,默认会变成“A同学 2024”;如果 end 不写,末尾会多一个换行。考试里经常让你判断“这段代码到底输出几行”,本质就是在考 end 参数会不会吞掉换行。

file 参数也很直观:默认是屏幕,但要写到文件,可以传一个文件对象。flush 平时很少改,但在需要实时看到进度的时候会设为 True。复习时不用死记,只要知道 print 是一个带旋钮的水龙头:sep 控制对象之间隔多远,end 控制最后一滴水落在哪,file 控制水流到哪个池子。

2.3 ifname== 'main':一段代码的“主角开关”

项目正文里有一条复习点:if __name__ == '__main__'是为了保证代码的可重用性。这句话不好懂,我们换个说法:每个 .py 文件都有两种身份。当你直接运行它时,它是主角;当另一个文件 import 它时,它是配角。__name__是 Python 自动放好的身份牌,主角牌子上写'__main__',配角牌子上写文件名。

# helper.py def hello(): print("你好") if __name__ == '__main__': hello()

直接运行python helper.py,会打印“你好”;在另一个文件里import helper,什么也不会打印,只有调用helper.hello()才打印。为什么要有这个开关?因为很多 .py 文件既能自己跑,也要能被别人调用。如果 import 时把自己的测试代码也执行一遍,别人还没用就莫名其妙输出一堆东西,那“可重用”就无从谈起。

期末选择题爱这么出:有两个 .py 文件,一个 import 另一个,问运行后会输出什么。如果你记得“主角开关”,一眼就能看出:被 import 的文件不是主角,它只在判断外面执行 import 级别的代码。所以,把“可复用的函数定义”放在判断外面,把“只想自己运行时看的测试调用”放在判断里面,就不会翻车。

3. 列表、元组、字典、集合:怎么选容器才不会翻车

3.1 可变与不可变:先看“能不能原地改”

Python 的数据类型很多,K12 期末最常挑“可变不可变”来考。一句话定义:列表、字典、集合是可变类型;数值、字符串、元组是不可变类型。

打个比方:可变类型像一个能随时加隔层、拆隔层的收纳箱,你可以往里面塞东西、取出来、换位置;不可变类型像一个刻好的印章,印章上的字一旦刻好就不能改,想换字只能重新刻一个。字符串看起来能改,其实每一次拼接和替换都是重新生成一个新字符串,原来的字符串始终没动。

为什么这个区分那么重要?因为它决定哪些操作可以原地完成,哪些必须换新对象。列表支持 append、pop、del;元组没有这些方法,只能整体重新生成。同样是“修改”,列表是“在同一个盒子里捣鼓”,元组是“换一个盒子”。

这里有个非常经典的单元素元组考点:

A = (3) # 整数 3 B = (3,) # 元组,只有一个元素 3

区别就在一个逗号。Python 识别元组靠的是逗号,不是括号。A = (3)只是加了括号的整数;B = (3,)才是元组。题目问“A 的数据类型”,好多人看到括号就写 tuple,结果丢了分。

另外,元组访问速度比列表快一点。如果题目只要求遍历,不要求修改,用元组更稳。这也是元组存在的意义之一:不打算改的数据,就用一个没法改的容器装着,反而省心和安全。

3.2 列表的“身份”与“复制”:同一个对象还是另一个对象

很多同学认为“列表赋值就是在复制内容”,这是期末复习里最危险的错觉。来看两段代码:

x = [1, 2, 3] y = x # 没有复制,只是给同一个列表起了小名 z = x[:] # 切片,创建新列表

y 和 x 指向同一个列表对象,id 相同;z 是新建的对象,id 与 x 不同。因为 y 和 x 是同一个对象,所以y.append(4)之后,x 也变成 [1, 2, 3, 4];而 z 怎么修改都不影响 x。究其原因,y = x只是把“x 的地址”复制给了 y,而不是把列表内容重新复制了一份。

列表的切片属于浅复制。为什么叫“浅”?因为它只复制第一层。如果列表里装的是整数这类不可变元素,浅复制就足够;如果列表里还套着列表,浅复制不会去复制内层列表,内层仍然共享。期末考试一般不往深了考,但你要能说出“浅复制”三个字,才能在判断题里分清“会改到原列表”和“不会改到原列表”。

如果需要删元素,del x[0]删除第一个元素,del x删除整个列表;pop()不带参数默认删最后一个,pop(i)按下标删。这些都是列表“可变”的具体表现。复习时多问一句:这个操作是原地改,还是返回新东西?原地改的通常返回 None。

3.3 集合与字典:去重很方便,但规则也多

集合和字典都用花括号,看起来像亲戚,用途完全不同。

集合的核心卖点是自动去重和自动升序。把一串输入丢进 set,重复值自动消失。不过集合有三大限制:不支持下标访问;不能 del 部分元素;元素必须是不可变类型。所以集合里可以放元组,不能放列表。原因很简单:集合的底层逻辑是“让元素按规则互不重复”,如果元素本身可变,它的身份会变来变去,集合的规则就乱了。

字典则是“键到值”的映射结构。键不能重复,值可以重复;键必须是不可变类型,字符串、元组都能当键,列表不能当键。字典不支持双向索引:你可以用键查值,但不能拿值反查键。想遍历字典,用keys()拿键列表,values()拿值列表,items()拿键值对列表。为什么需要这三种方法?因为“字典没有下标”,想要什么就先拿到对应的“名单”。

一个很实用的去重组合是“字符串转集合再拼回字符串”:

s1 = list(set(input())) s1.sort() print(''.join(s1))

它先把字符串拆成字符,用 set 去重,转回列表排序,最后用空字符串拼回去。题目要求“输出去重后按编码排序的字符串”时,这是标准答案。注意:集合虽然自动升序,但“自动顺序”不是编程接口,不能依赖它输出。要保留“第一次出现顺序”,得用另一招,这一招我们放到排序章重点讲。

4. 排序与去重:考卷上最容易翻车的三件事

4.1 sort、sorted、reverse、reversed:改不改原列表是分界线

先说结论:list.sort()是原地排序,没有返回值;sorted(list)返回新列表,不碰原列表。这两者的区别是 K12 期考排序题的第一考点。

a = [3, 1, 2] b = a.sort() print(b) # None print(a) # [1, 2, 3]

很多新手第一次写b = a.sort()时,特别自然以为 b 会得到排好序的列表,结果 print(b) 输出 None。为什么?因为 sort 方法把结果“留在了自己身上”,不会交还给左边的变量。用大白话说,它是“就地整理房间”,整理完不会给你拍一张新照片。

想拿到新列表,就用 sorted:

c = [3, 1, 2] d = sorted(c) print(d) # [1, 2, 3] print(c) # [3, 1, 2]

同理,reverse()是原地逆序,返回 None;reversed(x)返回一个迭代器。切片[::-1]是另一条路,它直接生成一个新列表,不改变原列表。项目正文里专门提过:切片方式因为要复制所有元素,所以更占内存,但好处是原列表保留。做题时如果题目说“在原列表上逆序”,就用list.reverse();如果说“得到逆序后的新列表”,用[::-1]或 reversed 更合适。

那为什么 sort 不是返回列表?因为 Python 想让调用者明确“你是要改这个列表,还是要新建一个列表”。如果改变和获取新结果混在一起,代码很容易产生歧义。理解了这一点,就不会把 None 当成 bug。

4.2 key 参数:自定义排序才是进阶分水岭

默认排序只能排数字大小或字符串字典序,但期末常出现“按每个数的数位之和排序”这种题目。此时必须用 key 参数。

n = int(input()) m = int(input()) s = list(range(1, n + 1)) s.sort(key=lambda x: sum(int(i) for i in str(x))) print(s[m - 1])

这段代码的意思是:把 1 到 n 都放进列表,排的时候不直接比 x 本身,而是先把 x 转成字符串,再逐位转 int 求和,用这个“数字和”作为排序键。lambda 是一个没有名字的小函数,它接收一个参数 x,返回一个“排序时要比较的东西”。由于 Python 的 sort 是稳定排序,数字和相同的两个数会保持原来的相对顺序,正好符合“数位和相等时按原值从小到大”的常见题意。

同样的逻辑还能用来“按第一次出现顺序去重”:

s1 = input().split(',') s2 = list(set(s1)) result = sorted(s2, key=s1.index)

s1 是原始顺序,s2 是去重后的结果,key=s1.index让排序参照原始列表的下标,等于把“第一次出现的位置”作为顺序依据。项目正文里有个更简洁的总结:sort 有两个可选参数,key 接收函数,reverse 接收布尔值。比如key=str.lower可以让字符串忽略大小写排序,这在处理含大小写的姓名列表时很实用。

为什么 key 值得单独复习?因为默认排序只有一个标准,而题目里的排序标准千奇百怪:按长度、按末位、按数位和、按出现顺序。学会 key,就是学会告诉 Python:“别按你默认的排,按我指定的规则排。”

4.3 桶排序:计数器思想是频次统计的核心

桶排序是 K12 算法题和期末都喜欢的思路,但它的本质不是“高大上”,而是“给每个可能的值准备一个桶,遍历时往对应的桶里放一个记号”。最经典的场景是统计每个自然数出现次数:

n = int(input()) num_list = list(map(int, input().split())) count_dict = {} for num in num_list: count_dict[num] = count_dict.get(num, 0) + 1 sorted_nums = sorted(count_dict.keys()) for num in sorted_nums: if count_dict[num] > 0: print(num, count_dict[num])

这里的 count_dict 就是一组桶:以数字为键,以次数为值。count_dict.get(num, 0)的意思是:如果 num 之前出现过,取旧值;如果没出现过,就当作 0,再加 1。这样第一次遇到的数字也能正确入桶。

桶排序的好处是一次遍历就能拿到频次信息,时间复杂度低。但它有前提:数据范围不能太大、太散。如果输入的数字最小 1、最大一亿,你不可能开一亿个桶;这时更适合用字典按需计数。期末考场上,看到“统计出现次数”先不要急着写桶,先想想数字范围有多大、有多少个不同的数。桶的思想是对的,但“桶”的载体要对。

4.4 二分查找:有序,是它敢“跳着找”的前提

二分查找是期末复习点里最有“算法感”的一个。思路用一句话讲:在一个已经排好序的列表里,每次看中间的数,比目标大就到左半边找,比目标小就到右半边找,不断把范围砍半,直到找到或找空。

def find(nums, target): left, right = 0, len(nums) - 1 while left <= right: mid = (left + right) // 2 if nums[mid] == target: return mid elif nums[mid] < target: left = mid + 1 else: right = mid - 1 return -1

注意调用前必须排序。如果列表无序,中间值和目标的大小关系不能说明目标在哪一半,二分查找就变成了乱猜。很多同学背熟了 while 模板,却忘了“先排序”这个前提,结果查找失败。复习时要把两件事绑定在一起:看到二分查找,第一反应不是循环,而是“有序”。

二分查找的价值在哪里?对大规模数据,排序一次要 O(n log n),之后每次查找只需 O(log n)。如果有多次查找,先排序再二分非常划算。但如果数据量很小,排序的损耗可能比直接扫描还大,这时候用线性查找就够了。期末不会让你分析复杂度,但你至少要知道:二分查找不是万能的,它的“能”建立在有序之上。

5. 常见误区与易混点:容易丢分的“想当然”

期末复习到最后,真正拉开差距的不是大算法,而是一堆看起来很小、特别容易想当然的陷阱。下面这五组是最常考、也最常错的。

5.1 元组与列表:逗号决定命运

易混点:(3)和(3,)看起来几乎一样,但一个是整数,一个是元组。

为什么混:因为很多人以为元组就是“带括号的列表”,忽略了元组靠逗号组成,而不是靠括号。其实A = 1, 2也会得到元组(1, 2),括号更多是为了可读性。

怎么区分:用type()一看就知道。写元组时,单元素必须加逗号:(3,)。没有逗号,(3)只是普通整数。项目正文里专门强调“元组只有一个元素时需要加逗号”,这是期末选择题最直接的考点。

另外,元组不能原地修改,没有 sort、reverse、append 这些方法。想对元组排序?只能先转换成列表,排完再转回来。很多同学试图用t.sort(),立刻报 AttributeError。做题时先问一句:我手里的是不是不可变对象?是的话,所有“原地修改”类操作都别用。

5.2 集合与列表:去重很方便,但别想按下标取

易混点:集合也能装好多值,就误以为能像列表一样用下标访问,比如s[0]。

为什么混:因为打印一个小整数集合时,它经常“自己排好序”,看起来像有序列表。这种“伪顺序”让人下意识以为它有下标。

怎么区分:列表是有序的序列,用a[0]取第一个;集合是无序的容器,不支持下标访问,也不是所有元素都有位置。整数集合的升序只是它内部存储的副产品,不是编程接口。所以del s[0]是错的;del s可以删除整个集合,但不能删集合里的“第一个”。

集合元素还有类型限制:可以放元组,不能放列表。想验证是不是这样,写一句{[1, 2]}就会看到 TypeError。为什么列表不行?因为列表可变、可哈希性不稳定,集合无法判断“它是不是出现过”。考前记住“元组能进集合,列表不能进集合”就够了。

5.3 字典的键:不可变才是“上岗证”

易混点:以为字典的键可以像列表下标一样随便换类型,甚至拿列表当键。

为什么混:键从形式上看就是一个值,值可以是任何类型,于是键也容易被当成“任何类型都行”。

怎么区分:字典的键必须能被哈希,也就是必须不可变。字符串、数字、元组可以当键;列表、字典、集合这种可变对象不能当键。因为键相当于字典的“索引标签”,如果标签本身会变,字典就没法稳定维护对应关系。所以题目问“哪个不能做字典的键”,看到带方括号的列表就直接排除。

字典的另一个易混点是“双向索引”。你能用键查值,但不能用值查键。如果想知道“值等于 x 的键是哪个”,必须用 items() 遍历,手动比较值。“字典的键不允许重复,值允许重复”,这两句也要连在一起记。

5.4 切片赋值:a[:0] 是在开头插入,不是取第 0 个元素

易混点:a[:0]看起来像是在取“第 0 个元素前面的内容”,实际上它在等号左边时是“在开头插入”。

为什么混:因为a[0]是取元素,a[:0]多了一个冒号,初学者会把它理解成“取一个空范围”,不确定空范围能干什么。

怎么区分:切片返回的是列表的一个区域。a[:0]是“从最开头到下标 0 之前”的空区域,等号左边时,把右边列表塞进这个空区域,结果就是在开头插入:

x = [3, 4] x[:0] = [1, 2] print(x) # [1, 2, 3, 4]

同理,a[0:0]也可以。这个知识点不常让手写,但经常出现在选择题里:问“执行后列表是什么”。只要记住“冒号出现时,右端是切片;等号左边时,切片的位置用来放新值”,就不会慌。

5.5 下划线命名:_xxx、__xxx、xxx不是一回事

易混点:看到下划线就以为都是“私有”的意思,分不清哪一个才是 Python 真正保护的东西。

为什么混:三个写法都带下划线,教材又喜欢把它们放在同一道题里讲。

怎么区分:_xxx是约定俗成的“私有”,只是一个提醒,Python 不拦截;__xxx是会被 Python 改名的“私有”,解释器会把它变成_类名__xxx,外部访问原名会失败;__xxx__是 Python 的特殊方法或特殊变量,比如__init__,是解释器约定好的接口,不能随便拿来当私有名。

class Student: def __init__(self, name): self._name = name self.__score = 0 s = Student("A同学") print(s._name) # 能访问 print(s._Student__score) # 双下划线被改名

期末题常给你一段类代码,问“为什么访问 __score 报错”。正确答案不是“它私有”,而是“Python 对它做了名称管理,真名变成了 _Student__score”。能把这一句说到位,判断题基本就拿稳了。

提示:考试遇到拿不准的结构,先用type(x)看类型,再用dir(x)看它支持哪些方法。这不是万能药,但能挡住八成想当然。

6. 期末答题的边界判断:什么时候照搬套路,什么时候重新想

复习资料里的技巧越多,越需要判断力。不是每个方法都适用每道题。下面这张表,是期末考前最值得过一遍的场景对照:

需求推荐写法不推荐
去重且保留第一次出现顺序sorted(set(原列表), key=原列表.index)直接打印set(...)
只要去重,不管顺序list(set(...))依赖集合顺序做输出
原地排序且原列表可以改list.sort()sorted()再去赋值
需要一个新排序结果sorted(...)reverse()或原地 sort
统计自然数出现次数字典计数,再排序键开一个巨大的桶数组
多次查找目标值先排序,再二分查找不排序直接二分
只遍历不修改用元组用列表,安全性和速度都不如元组

最后一个具体例子。题目说“输入一串逗号分隔的名字,去重后按第一次出现的顺序输出”。许多人的第一反应是set(input().split(',')),结果输出顺序全乱。正确做法是:

s1 = input().split(',') s2 = list(set(s1)) result = sorted(s2, key=s1.index) print(result)

s1 保留输入顺序,set 负责去重,sorted 用key=s1.index把顺序找回。这就是“什么时候用集合去重、什么时候用排序兜底”的典型答案。

反过来也有别用的时候。数据量只有两三个数,直接比较比任何排序都省事;数据范围极大但很稀疏,开桶就是浪费;原列表后面还要用原顺序,就不能原地 sort。期末考的不是“哪种算法最厉害”,而是“这道题选哪招不翻车”。

我至今记得某次模拟,我兴高采烈地把a.sort()的结果直接 print,屏幕上明晃晃地输出 None,盯了好几分钟才反应过来:这个函数改变了列表本身,却没有把结果交回来。从那以后,我每次复习 Python 都强制自己走一遍三问:这个操作改不改原对象?返回给我什么?会不会破坏后面的数据?这份复习资料里的每一条,几乎都是类似的“血泪经验”,考前过一遍,比临时翻课件更能形成自己的判断。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表