ICS 考前冲刺:把 mock 16 题压回 W1–W3 的 11 个考点

明天就上 Module Test 1。你手上有一份 exercise.pdf 的 mock 模拟卷:30 分钟、16 题、标记 15 分制(最佳 15 题算分),覆盖 W1 表达式与类型、W2 控制流、W3 函数与容器三件套。今晚不是按章节复习的时间,而是按模拟卷题型反推考点的时间——每做错一题,立刻知道它回扣到 W1/W2/W3 的哪一节、漏想了哪一条规则。

这份冲刺专题把 16 道题压回 11 个核心考点:

桶模拟卷题号考点
W1 表达式与类型Q1, Q2, Q3算术优先级、/ 永远 float、比较运算返回 bool
W1 赋值 + W3 tuple swapQ4a, b = b, a 是同时赋值
W2 if/elif/elseQ5first match wins(按顺序匹配)
W2 forQ6按元素迭代
W2 accumulatorQ7初始化 → 循环里更新 → 循环外用
W2 whileQ8退出条件是边界状态
W3 函数:returnQ9return 的值可以继续参与运算
W3 listQ10.append() in-place 改 list
W3 tuple unpackQ11low, high = min_max(...) 按位置解包
W3 dictQ12.items() 解包 + .get() 默认值不增 key
W3 key-line 填空Q13, Q14, Q15return n % 2 == 1、small.append(n)、while 状态更新
W3 综合陷阱Q16return 是 exit 不是累加器

把这条映射表记下来——今晚剩下的每一分钟都围绕它转。错一题不要从头再来,先在表里找到它属于哪个桶,那一节就是今晚必须再看一眼的地方。


一、为什么按模拟卷题型复习,而不是按 W1→W2→W3 章节复习?

按章节复习的隐含假设是「我能把每章的内容都掌握」。考前一夜,时间不够。按模拟卷题型复习的好处是:每一道错题都直接对应你「今晚没掌握的那一条规则」——错 Q5 就是没掌握 first match wins,错 Q12 就是没掌握 .get() 默认值不增 key,不需要翻讲义、不需要重新看完整章。

讲义原本就是这样把 int/str 的 + 和 * 当考点设计的。看下面这张练习页:

图注:W1 讲义 Part A 练习页的 A/B/C/D 四段填空:print(3 + 5)、print("3" + "5")、print(3 * 5)、print("3" * 5)——四行代码看起来相近,但 Python 的运行结果分别是 8、35、15、33333。讲义下面追问:"Why can two things that look similar behave differently?" 模拟卷 Q1–Q3 完全沿用同一思路:int 决定 + 是加法、str 决定 + 是拼接,二者相遇 Python 直接拒绝(TypeError)。讲义 Part B 的标题「Variables are names」在这里被截断,但完整内容在 W1 讲义 Task 3(x = 5; y = x + 2; x = 10)里。

理解这张图的关键,是把它和后面 Q1–Q3 一一对应起来:print(3+5) 对应 Q1 的 10 - 2*3,讲优先级;print("3"+"5") 对应 Q3 的 2+3>4(虽然具体数字不同,但都是「同一种运算符,看类型决定行为」这条主线)。这两道题加上 Q2 的 6/2 是 W1 在模拟卷上的全部 3 道「预测输出」。

讲义还把 Python 出错信息分成了三类(syntax / runtime / logic)——这是阅读任何 Python 出错信息的地图:

  • syntax error:Python 读不懂你的代码。例子:print("Hello" 漏了右括号。Python 在「编译期」就拒绝了,根本不会去运行。
  • runtime error:Python 读得懂,但跑起来崩。例子:3 + "5" 抛 TypeError。Python 已经把你的代码读完、开始执行了,但执行到这一步发现「int 加不了 str」——这是运行时异常(exception),它会打一个 traceback 出来。
  • logic error:Python 跑通了,但答案错了。例子:折扣 0.2 写成了 20。Python 不会给你任何错误信息——它按你写的指令算,只是结果不是你想要的。

前两类是 Python 语言参考明确定义的:SyntaxError 在编译期抛出,runtime exception 在执行期抛出,由 Language Reference §4 Execution model 条款覆盖PythonExecModel; 第三类是教学概念,不在 Language Reference 里,但在 W1 deck 里被反复用「Errors are signals, not failures」定调。

三类错误对应到模拟卷:Q5 的 temp=8 走哪个分支、Q8 的 while i<20 在哪一步退出,都是 logic 类型——Python 不报错,但要靠你 trace 才知道对不对。Q13–Q16 里的填空题,如果填错关键字(比如 Q15 填了 i = i * 2 漏跳了一步),也属于 logic 错。今晚做的每道题,先在心里分一下桶:是 logic(要 trace)、runtime(要看抛什么错)、还是 syntax(看一眼就知道是漏括号还是漏冒号)。


二、Part A 预测输出(Q1–Q4):算术优先级、类型决定运算符、赋值是名字绑定、tuple swap 同时赋值

Part A 是 4 道「先猜再跑」的预测输出题。每一道都对应 W1 的一个核心考点,外加 Q4 偷偷埋了 W3 的 tuple swap。先过一遍图:

图注:左半边是算术优先级五级色框,从高到低依次是 **、* / // %、+ -、比较运算符(< > == 等)、赋值(=)。重点两条:* 比 + 紧,所以 10 - 2*3 先算 2*3=6 再算 10-6=4;/ 永远返回 float,所以 6/2=3.0 而不是 3。右半边是运算符重载五行对照:3+5→8、"3"+"5"→"35"、3*"5"→"555"、3*5=15、3+"5"→TypeError——同一个 +/* 在不同类型上有完全不同的行为。PythonTutorial

这张图同时解决模拟卷 Q1、Q2、Q3 三道题——这也是它放在这个位置的原因。

Q1:print(10 - 2 * 3) 答案 4,不是 24

* 比 - 紧,先算 2*3=6,再算 10-6=4。常见错误是把它当自然语言读「10 减 2 再乘 3」得到 24。Python 不按自然语言读,它按优先级读——50 - 5*6 = 20、(50 - 5*6)/4 = 5.0 都是这套规则PythonTutorial。

Q2:print(6 / 2) 答案 3.0,不是 3

/ 永远返回 float,即使能整除也是 3.0。要整数得用 //(向下取整,6 // 2 = 3)。Python Tutorial 原文是「division always returns a floating-point number」PythonTutorial。

Q3:print(2 + 3 > 4) 答案 True,不是 False

先算算术 2 + 3 = 5,再算比较 5 > 4 = True。常见错误是把它读成 2 + (3 > 4)——比较运算没有 + 紧。所以右半张图的「比较运算符」那一级色框就告诉你:算术跑完才轮到比较。True 是 Python 的 bool 类型,bool 是 int 的子类(True == 1、False == 0)——但 Q3 不考子类,只考 True/False 这个值PythonTypes。

Q4:a, b = b, a 答案 2(不是 1)

Q4 是这一节的关键陷阱。它出现在 W1 quiz 里,但实际考点是 W3 的 tuple 同时赋值。看代码:

a = 1
b = 2
a, b = b, a
print(a)

答案是 2。为什么不是 1(如果按「先 a=b 再 b=a」理解就错)?

Python Language Reference §7.2 给了一句话定调:「overlaps between the left-hand side and the right-hand side are 'simultaneous' (for example a, b = b, a swaps two variables)」PythonSimple。意思是:

  1. 右边的 b, a 先按 left-to-right 求值,拼成 tuple (2, 1)(用的是赋值前的旧值)
  2. 再把这个 tuple 解包到左边的 a, b:a=2, b=1

如果分两步写(先 a = b 再 b = a),第一步就把 a 覆盖成 2、旧值 1 丢了,第二步再 b = a 也只能拿到 2,结果 a = b = 2,根本没交换。

这一条同时也是 W1「赋值是 binding」的延伸——a = b 不是「让 a 永远等于 b」,而是「在那一刻把 a 这个名字指向 b 当时指的值」PythonExecModel。

补一张图,把这两件事串在一起看:

图注:左边 Model A「x is a box containing 5」是错的——把变量想象成装着值的盒子,y = x 时把盒子里的值复制一份给 y。但 Python 不是这样工作的。右边 Model B「x is a name currently referring to the value 5」才是对的——x 是一个名字,当前指向值 5。y = x 让 y 这个名字也指向 x 当前指的值;之后改 x(x = 10)只是让 x 重新指向一个新值,y 仍然指原来的 5,不会跟。PythonTutorial PythonExecModel

这一节的四道题讲完,今晚的 W1 主战场就过了——Q1–Q4 全部 4 题都能在 5 秒内说出答案:Q1: * 比 + 紧、Q2: / 永远 float、Q3: 算术先跑再比、Q4: a,b=b,a 是同时赋值。把这四条写下来贴在屏幕边上,进考场前扫一眼。


三、Part B 追踪(Q5–Q8):if first match wins、for 迭代、accumulator 三步、while 边界

Part B 是 4 道「逐行 trace」题。这一节的关键词是「state」——每个变量在每一行末尾是什么值,每一步往哪个方向走。

Q5:if/elif/else 是 first match wins

temp = 8
if temp < 0:
    print("freezing")
elif temp < 10:
    print("cold")
else:
    print("mild")

输出:cold。temp=8 不满足 < 0,跳到 < 10,满足,打 cold。即使 temp < 10 也满足「小于 100」「小于 1000」之类的更大条件,elif 也只按顺序匹配第一个真。

Python Language Reference §8.1 给的原文是「selects exactly one of the suites by evaluating the expressions one by one」PythonCompound——这就是 first match wins 的语言层依据。Q5 的陷阱不是「选 cold 还是 mild」,而是「选 cold 还是 freezing」——按顺序写,cold 排在前面,先匹配上,freezing 那条根本不会走。

Q6:for 按元素迭代

for fruit in ["kiwi", "fig"]:
    print(fruit)

输出(两行):kiwi、fig。for fruit in [...] 是按序列里的元素逐个迭代——不是按索引计数,是直接拿到元素本身。W1 没讲 for,W2 才有,所以 Q6 实际是 W2 的题。Python Tutorial §4.2 原话是「the for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence」PythonTutorial。

Q7:accumulator 三步骤

nums = [3, 8, 5, 12]
total = 0
for n in nums:
    if n > 5:
        total = total + n
print(total)

输出:20。n=3 skip,n=8 加进来 total=8,n=5 skip,n=12 加进来 total=20。W2 讲义用三句话钉住这个模式:「initialize before the loop / update inside the loop / use the result after the loop」。任何一步漏掉都出错:忘了初始化(total = 0)会抛 NameError: name 'total' is not defined;忘了在循环里更新(只初始化不累加)会一直打 0;忘了在循环外用(循环里 print)会打 4 次中间值。

Q7 的陷阱不是「加起来多少」,而是「是不是在 if 内部更新」。如果写反(先 if n > 5: 内部再 total = total + n),Python 缩进一错就完全走样。W3 讲义重申了一遍「accumulator pattern: initialize before the loop / update inside the loop / use the result after the loop」PythonTutorial。

Q8:while 边界陷阱(这是今晚最容易错的一道)

i = 1
while i < 20:
    print(i)
    i = i * 2

逐行 trace 一遍:

步骤进入循环前 ii<20?print(i)然后 i=i*2 → i
11是12
22是24
34是48
48是816
516是1632
632否,退出——

print(i) 在 i = i * 2 之前执行。所以 print 出来的最后一行是 16——i=16 时进 body,打 16,然后 i 变 32;下一次判断 i=32 不满足 i<20,循环退出,32 永远不会被 print。Python Tutorial §3.2 的 Fibonacci 例子是同一模式:a, b = 0, 1; while a < 10: print(a); a, b = b, a+b 输出 0 1 1 2 3 5 8,最后一行是 8 而不是 a=13——print 永远在 update 之前PythonTutorial。

注意一个细节:answer key 里 Q8 的答案是 32——但那是循环退出后 i 的最终值(i=32),不是 print 出来的最后一行(最后一行是 16)。题目问的是 "What prints, line by line?",所以 print 出的五行是 1, 2, 4, 8, 16。最容易翻车的两个错答是:16(以为 print 在 update 之后)和 20(以为会经过 20)。两个都错——print 始终在 update 之前,i 永远不会经过 20(1→2→4→8→16→32 已经跳过了 20)。

这一节收尾:Q5–Q8 全部 4 题的考点是四件事——if 按顺序匹配、for 按元素迭代、accumulator 三步、while 退出条件看状态。Q8 的边界陷阱一定要自己手写一份状态表,别只在脑子里想。


四、W3 易错专场(Q9–Q12):def 不跑 body、argument 与 parameter 不同、return 是给程序的、函数里的 x 不是外面的 x

W3 是 W1/W2 之后的「函数 + 容器」综合战场。Q9–Q12 全是函数题,每一道都考一个独立坑:return 的值能不能继续运算、.append() 返回什么、tuple unpack 怎么按位置、dict .get() 到底改不改 dict。

Q9:return 的值可以继续参与运算

def add(a, b):
    return a + b

print(add(2, 3) + 1)

输出:6。add(2, 3) 返回 5(不是打 5),5 + 1 = 6,print 打 6。常见错误是把它当成 print 版:def add(a, b): print(a + b); print(add(2, 3) + 1)——这样会先打 5,然后 add(2, 3) 返回 None,None + 1 抛 TypeError。

Python Language Reference §7.6 给了 return 的三条权威定义:(1) return 必须出现在函数定义里;(2) 如果有 expression 就求它的值,否则 None is substituted;(3) return 退出当前函数调用,把表达式的值(或者 None)作为返回值PythonSimple。

这就把 None trap 钉死了:「没有 return 拿到 None」不是 Python 的 bug,是规范。def square(x): print(x*x); y = square(4); print(y) 会先打 16(print 那一行),然后打 None(y 拿到 None)。问诊时你答对过这道——但 Q9 反过来考:return 出来的值是给程序的,可以继续 + 1。

Q10:list 的 .append() 改原 list

nums = [5, 3, 9]
nums.append(1)
print(nums)
print(len(nums))

输出:[5, 3, 9, 1] 然后 4。.append(1) 在 list 末尾加一项,原 list 被改——.append() 返回 None(不改返回值那侧),但 list 本身已经被改了。len(nums) 数 4 项。

注意和 W1 的对比:W1 里 x = 5; y = x; x = 10 后 y 还是 5(数字 immutable,y 只是抓了那一刻的值);list 是 mutable,nums.append(1) 是 in-place 改动——所有指向这个 list 的名字都看得到这个改动。Python Tutorial §3.1.3 原话是「simple assignment in Python never copies data. When you assign a list to a variable, the variable refers to the existing list. Any changes you make to the list through one variable will be seen through all other variables that refer to it」PythonTutorial; rgb` 同对象引用演示。")。

Q11:tuple 按位置解包

def min_max(nums):
    return min(nums), max(nums)

low, high = min_max([7, 2, 9])
print(high - low)

输出:7。min_max([7, 2, 9]) 返回 tuple (2, 9),low, high = ... 按位置解包:low = 2, high = 9,high - low = 7。

Q11 的陷阱有两个:第一个是 tuple 与 list 的写法差(return min, max 是 tuple packing,不需要加括号);第二个是解包时名字位置不能换——low, high 反过来就是 low=9, high=2,high - low 就是 -7。W3 讲义把这条规则说成「ONE return, TWO values」——return a, b 自动 pack 成 tuple,caller 按位置 unpackPythonTutorial。

Q12:dict .items() + .get() 默认值不增 key

prices = {"tea": 12, "cake": 25}
total = 0
for item, price in prices.items():
    total = total + price
print(total)
print(prices.get("juice", 0))

输出:37 然后 0。.items() 一次给出 (key, value) 对,所以 for item, price in prices.items() 解包出 item="tea", price=12 和 item="cake", price=25,累加 12 + 25 = 37。然后 prices.get("juice", 0)——key 不存在,返回默认值 0,但 dict 里没加新 key。

Q12 的陷阱:很多人以为 .get(key, default) 会把默认值塞进 dict,所以预期「第二次打 0 + 1 = 1」(以为 get 给 default 同时把 juice 加进去了)。错。.get() 只读不写。Python Tutorial §5.5 原话是「Extracting a value for a non-existent key by subscripting (d[key]) raises a KeyError. To avoid getting this error when trying to access a possibly non-existent key, use the get() method instead, which returns None (or a specified default value) if the key is not in the dictionary」PythonTutorial。

局部作用域:你问诊时答错的那道题

问诊时你答过一道:

def add(n):
    x = n + 1
    return x

n = 5
print(add(n))
print(n)

你答成 6——以为 add(n) 里改了 x 会连带把外面的 n 改成 6。这道题实际上是 W3 「局部变量 + 值传递」的经典坑。

Python Language Reference §4.2.2 给了这条权威条款:「If a name binding operation occurs anywhere within a code block, all uses of the name within the block are treated as references to the current block」PythonExecModel。

套到例子里:add(n) 调用时,n 这个值(5)被复制到 add 函数自己的 local symbol table 里作为 parameter(在 def 里看是 n,在 call 里看也是 n——argument 与 parameter 是「同一个名字的两半」,不是「同一个对象」PythonGlossary)。函数体里写 x = n + 1——x 是函数内的 local name,不是外面那个 x(外面那个根本没出现)。函数返回 6。回到外层 print add(n) 打 6,然后 print n 还是 5。

类比一句话(不展开):不同作用域里重名的变量,就像不同文件夹里可以重名的文件——文件名相同,但内容是各自的。

这一节收尾:Q9–Q12 全部 4 题的考点是四件事——def 写菜谱调用才做菜、argument 与 parameter 是同一次相逢的两半、没有 return 拿 None、函数内赋值让它局部。Q9 错在把 return 当 print,Q10 错在把 .append() 当纯函数(不改原对象),Q11 错在解包名字放反,Q12 错在以为 .get() 会塞默认值进 dict。这四个坑恰好覆盖 W3 函数和容器的全部高频陷阱。


五、容器三件套 + Part C/D 关键行(Q10/Q13–Q15):list、tuple、dict 的核心差异

这一节把 W3 的容器三件套(list / tuple / dict)合起来讲,每种容器配一道模拟卷对应题巩固。

list:0-based 索引 + .append() 改原列表

list 是 mutable、0-based 索引、.append() 加末尾。看下面这张图:

图注:列表 nums = [10, 20, 30, 40, 50] 五个单元格。上方索引 0 到 4(0-based),下方负索引 -5 到 -1。中间三格(20、30、40)用橙色边框高亮,对应 nums[1:4]——也就是 i=1、j=4,Python 把 j 不含进去,只取 i ≤ k < j 的部分。nums[1:4] = [20, 30, 40],不包含 50。底部公式 i <= k < j 是「半开切片」的核心PythonTypes。

Q10 已经讲过(nums.append(1) 后 print + len)。Q14 也用 list——但 Q14 测的是「过滤」模式:用空 list + .append() 把符合条件的元素挑出来:

nums = [4, 7, 2, 9]
small = []
for n in nums:
    if n < 5:
        ____
print(small)

答案填 small.append(n)。跑一遍:n=4 满足 < 5,append 进 small;n=7 skip;n=2 满足,append;n=9 skip。最后 small = [4, 2]。W3 讲义 Part H 把这条规则叫做「Build a list dynamically (the accumulator pattern, on a collection)」——先空列表,循环里 .append() 符合条件的元素,循环外用。

tuple:immutable + 同时赋值 + unpack

tuple 和 list 的关键差别是 immutable——tuple 写完不能改(point[1] = 9 抛 TypeError)。但 tuple 有个独特的能力:多返回值 + 解包。

Q4(a, b = b, a)和 Q11(low, high = min_max(...))都靠 tuple 完成。Python Tutorial §5.3 原话是「multiple assignment is really just a combination of tuple packing and sequence unpacking」PythonTutorial。

Q15 也用 tuple 思想——while 循环里更新 i:

i = 2
while i <= 6:
    print(i)
    ____

填 i = i + 2 或 i = i + 1。两种填法跑出不同结果:

  • i = i + 2:i 序列是 2, 4, 6(然后 8 不满足 i <= 6 退出),输出 2, 4, 6 三行。
  • i = i + 1:i 序列是 2, 3, 4, 5, 6(然后 7 不满足),输出 2, 3, 4, 5, 6 五行。

answer key 给的答案是 i = i + 2——因为题目要求「Print 2, 4, 6, one number per line」。

dict:按 key + .get() 安全 + .items() 计数模式

dict 是 mutable、按 key 查找、d[key] 缺失抛 KeyError、.get(key, default) 安全读默认值不增 key、.items() 一次给 (key, value) 对。

Q12 已经用到了 .items() + .get()。Q13 也考 dict 相关的 list 操作,但 Q13 实际上不考 dict——Q13 考的是函数体内的 return n % 2 == 1:

def is_odd(n):
    ____

填 return n % 2 == 1。n % 2 给余数,余 1 是奇数(返回 True),余 0 是偶数(返回 False)。== 1 比较出 bool。

这里有个 W3 测验没直接考但和 Q12 同类的 dict 计数模式——counts[w] = counts.get(w, 0) + 1:先 .get(w, 0) 安全读当前计数(不存在返回 0),加 1,再写回。W3 测验 Q8 也是同类:stock["pen"] = stock["pen"] - 1(用 [] 而非 .get(),因为 key 一定存在)+ stock.get("eraser", 0)(key 不存在,用 .get() 给默认值 0,不增 key)——这两个用法一组合就是 dict 的标准操作。.get() 这种「只读不写、缺失给默认值」的写法由 Python Tutorial §5.5 介绍PythonTutorial;而 counts[w] = counts.get(w, 0) + 1 这条「dict counting accumulator」模板本身出自 W3 学习讲义 Part J Task 3。

这一节收尾:list、tuple、dict 三件套的考点是四件事——list 改原对象、tuple immutable 但能打包解包、dict .get 安全读默认值不增 key、filter 用空列表 + append。Q10/Q14 是 list,Q4/Q11/Q15 是 tuple(其中 Q15 间接),Q12/Q13 是 dict/return。Q13–Q15 全部 4 道 key-line 填空都能在 10 秒内填完。


六、Part D 挑战 Q16 + 限时 30 分钟实战 + 考前扫一眼清单

Q16 是 W3 的综合陷阱题——也是昨晚最容易翻车的位置:

def sum_evens(nums):
    total = 0
    for n in nums:
        if n % 2 == 0:
            return total + n
        total = total + n
    return total

print(sum_evens([1, 2, 3, 4]))

问:(a) 实际输出什么?(b) 哪个关键字让输出错了?应该输出什么?

(a) 实际输出 3

trace 一遍:n=1 不是偶数,skip if,total = total + n 让 total = 1。n=2 是偶数,进 if,return total + n = 1 + 2 = 3——函数立刻退出,不再访问 n=3 和 n=4。所以输出 3。

(b) 关键字 return 让输出错了;应该输出 6

正解是 total = total + n 写两遍:if 里更新 total(不 return)、for 循环结束后 return total。跑一遍正解:

n偶数?进 if?total 之后是否 return
1否否0(不动)否
2是是0 + 2 = 2否
3否否2(不动)否
4是是2 + 4 = 6否(循环结束)
————是,return 6

正解返回 6,因为只累加偶数 2 + 4 = 6。问题出在 if 里不应该写 return total + n——应该写 total = total + n,让 if 只是个 update,不 exit。然后循环结束统一 return total。这就是「return 是 exit 不是累加器」这一句。

Python Language Reference §7.6 已经说过「return leaves the current function call with the expression list (or None) as return value」PythonSimple。Q16 是「return 是 exit 不是累加器」这条规则的标准考题。

Q16 把 W2 accumulator 和 W3 return 绑到一起考:accumulator 必须「循环里更新 + 循环外用」,任何在循环里提前 return 的写法都会跳过剩余元素。模拟卷的 answer key 给的正是 3 + return 这个关键字 + 应该输出 6。

现在做一遍 mock

下面是你今晚应该按的步骤:

  1. 打开 exercise.pdf。设 30 分钟闹钟,独立做完全部 16 题,关书、关 AI、关浏览器。
  2. 对照 answer key 自评(标记 15 分制,最佳 15 题算分)。
  3. 错题逐条对照表:
题号考点回扣到本专题
Q1–Q3算术优先级、/ float、比较运算二(Q1/Q2/Q3)
Q4a, b = b, a 同时赋值二(Q4)
Q5–Q8if/for/while/accumulator三(Q5–Q8)
Q9–Q12return vs print、list、tuple、dict四(Q9–Q12)
Q13–Q15return、.append()、while 更新五(Q13/Q14/Q15)
Q16return 是 exit 不是累加器六(Q16)
  1. 错题回扣到对应小节再看一遍——不要从头再过整本讲义,只看错的那一条。
  2. 睡前把下面这 12 条 checklist 在脑子里过一遍。

考前扫一眼的 12 条 checklist

其中 Q16(return vs accumulator)、Q12(dict .items() / .get())、Q8(while 边界)是综合风险点:

  1. ** 高于 - 一元运算:−3**2 == −(3**2) == −9,不是 9。
  2. 运算符重载看类型:3 + 5 = 8、"3" + "5" = "35"、3 * "5" = "555"、3 + "5" = TypeError。
  3. 赋值是 binding,不是数学等式:y = x + 2 后改 x 不影响 y(数字 immutable)。
  4. / 永远 float:6 / 2 = 3.0 不是 3;要整数用 //。
  5. list 是 mutable in-place:nums.append(1) 改原 list,所有引用都看得到;nums = nums + [1] 才是新建 list。
  6. def 不跑 body:def greet(): print("Hi") 单独存在时什么都不打,要 greet() 才打。
  7. print 不 return:def square(x): print(x*x) 单独存在时,调用 square(4) 打 16 但返回值是 None;y = square(4) 让 y = None。
  8. 函数里的 x 是局部变量:函数内对 x 的任何赋值都让它成为局部的,与外层 x 无关(Python Language Reference §4.2.2)。
  9. range 0-based stop-excluded:range(5) = 0, 1, 2, 3, 4 不含 5;list slicing nums[1:4] 同样不含 4。
  10. a, b = b, a 是同时赋值(§7.2):RHS 先求值成 tuple,再 unpack 到 LHS;分两步写不会交换。
  11. dict[key] 缺失抛 KeyError;dict.get(key, default) 安全读默认值,但不增 key。
  12. return 是 exit 不是累加器:循环里提前 return 会跳过剩余元素;accumulator 必须在循环外 return。

把这 12 条写在纸上(不是默背),明早考前一小时过一遍。今晚做完 mock、对完答案后回扣完错题,就睡觉。

收尾一句话

今晚你的目标不是「把 W1–W3 全部再看一遍」——那个目标对一晚上来说太大了。你的目标是「把 exercise.pdf 16 题每道都 self-trace 出正确答案,错一道立刻知道回扣到哪」。这一条做到了,Module Test 1 的 80% 你已经拿稳了。

模拟卷 answer key 最后那句「same skills, new surface」很重要——实考题不是这套题,但考点是同一套。错题回扣到本专题对应小节,吃透每一条规则,比刷完五套模拟卷更有用。

祝明早考试顺利。


参考文献

本专题引用的核心资料如下,建议深入学习时阅读原文:

  1. The Python Tutorial — https://docs.python.org/3/tutorial/index.html
  2. Python Language Reference: §4 Execution model — https://docs.python.org/3/reference/executionmodel.html
  3. Python Library Reference: Built-in Types — https://docs.python.org/3/library/stdtypes.html
  4. Python Language Reference: §8 Compound statements — https://docs.python.org/3/reference/compound_stmts.html
  5. Python Language Reference: §7 Simple statements — https://docs.python.org/3/reference/simple_stmts.html
  6. Python Glossary — https://docs.python.org/3/glossary.html
ICS 考前冲刺:把 mock 16 题压回 W1–W3 的 11 个考点