Companion to the Practice Set · Mark-by-mark walkthroughs · AP CSP-Feeder / US / ON / BC / AB styles练习题配套详解 · 逐分讲解 · AP CSP 衔接 / 美 / 安 / 卑 / 阿省考风格
Given temps = [15, 22, 18, 30, 27], which statement is correct?给定 temps = [15, 22, 18, 30, 27],以下哪个说法正确?
temps[2] has value 18答案:(B) - temps[2] 的值为 18Zero-based indexing: index 0 = 15, index 1 = 22, index 2 = 18, index 3 = 30, index 4 = 27. [1]从零开始索引:索引 0 = 15,索引 1 = 22,索引 2 = 18,索引 3 = 30,索引 4 = 27。[1]
temps[2] = 18, not 22. Index 1 holds 22. [1]temps[2] = 18,不是 22。索引 1 存储 22。[1]len(temps) = 5 (five elements). Incorrect.len(temps) = 5(共五个元素)。不正确。len - 1. Memorise: length 5, last index 4. Option (A) traps students who count from 1; option (D) traps students who confuse the length with the last valid index.从零开始的索引是数据结构题目中考查最多的概念。第三个元素在索引 2(不是 3),最后一个有效索引始终是 len - 1。记住:长度 5,最后索引 4。选项 (A) 陷阱针对从 1 开始计数的学生;选项 (D) 陷阱针对把长度与最后有效索引混淆的学生。What does the program with range(0, 3) and data = [10, 20, 30, 40, 50] output?带 range(0, 3) 和 data = [10, 20, 30, 40, 50] 的程序输出什么?
60答案:(C) - 60range(0, 3) produces indices 0, 1, 2 only (upper bound is exclusive). [1]range(0, 3) 仅产生索引 0、1、2(上界为排他)。[1]
i | data[i] | total aftertotal 更新后 |
|---|---|---|
| 0 | 10 | 10 |
| 1 | 20 | 30 |
| 2 | 30 | 60 |
10 + 20 + 30 = 60. [1] Options (A) 150 sums all five; (B) 90 sums indices 0-2 of the wrong list; (D) 100 is incorrect. [1]10 + 20 + 30 = 60。[1] 选项 (A) 150 是全部五个之和;(B) 90 错误;(D) 100 不正确。[1]
range(start, stop) excludes the stop value. range(0, 3) gives 0, 1, 2 -- three iterations. The most common error is to include index 3 (giving 10+20+30+40=100), forgetting Python's exclusive upper bound rule.range(start, stop) 不包含终止值。range(0, 3) 给出 0、1、2 共三次迭代。最常见错误是包含索引 3(得 10+20+30+40=100),忘记 Python 上界排他规则。List operations on cart.对 cart 执行列表操作。
cart: ["apples", "milk", "eggs"] (b) "bread" shifts right to index 2 (c) remove by value vs pop by index(a) cart 最终内容:["apples", "milk", "eggs"] (b) "bread" 右移到索引 2 (c) 按值删除 vs 按索引删除| Operation操作 | cart after操作后 cart |
|---|---|
| append("apples") | ["apples"] |
| append("bread") | ["apples", "bread"] |
| insert(1, "milk") | ["apples", "milk", "bread"] |
| remove("bread") | ["apples", "milk"] |
| append("eggs") | ["apples", "milk", "eggs"] |
Final: ["apples", "milk", "eggs"]. [2]最终:["apples", "milk", "eggs"]。[2]
insert(1, "milk") places "milk" at index 1. The element previously at index 1 ("bread") shifts right to index 2. All elements at and after the insertion point move one position to the right. [2]insert(1, "milk") 将 "milk" 放置在索引 1 处。原来在索引 1 的元素("bread")向右移动到索引 2。插入点及之后的所有元素均向右移动一位。[2]
remove("bread") finds and deletes the first element equal to the given value, while pop(1) removes the element at index 1 by position and returns it. [1]remove("bread") 按值查找并删除第一个等于该值的元素,而 pop(1) 按位置删除索引 1 处的元素并返回它。[1]
pop(2); if asked to "remove the element with value X," use remove(X). Confusing these is a mark-losing error in Ontario ICS3U A1.6 questions.AP CSP AAP-2.K 将 APPEND、INSERT、REMOVE 和 LENGTH 列为四种必考列表操作。考试中,若被要求"删除位置 2 的元素",用 pop(2);若被要求"删除值为 X 的元素",用 remove(X)。混淆两者是安大略 ICS3U A1.6 题目中常见的失分错误。Choose the most appropriate data structure for each scenario.为每个场景选择最合适的数据结构。
Use a tuple: (latitude, longitude). A tuple is immutable, so the coordinate cannot be accidentally changed once set. It is also ordered and indexed, giving O(1) access to either component. [2]使用元组:(纬度, 经度)。元组是不可变的,因此坐标设定后不会被意外更改。它也是有序且可索引的,对任一分量提供 O(1) 访问。[2]
Use a 2D array: image[row][col]. Grid-shaped data with natural row/column coordinates maps directly to a 2D array, giving O(1) access to any pixel. Ontario ICS4U A3.5 and AB CSE2120 1.2.1 both cite image processing as a canonical 2D array application. [2]使用二维数组:image[行][列]。具有自然行列坐标的网格形状数据直接映射到二维数组,提供对任意像素的 O(1) 访问。安大略 ICS4U A3.5 和 AB CSE2120 1.2.1 均将图像处理列为典型二维数组应用。[2]
Use a set: submitted = {"Alice", "Bob", ...}. Set membership testing (name in submitted) is O(1) on average, far faster than searching a list (O(n)). Sets also automatically prevent duplicate entries. [2]使用集合:submitted = {"Alice", "Bob", ...}。集合成员测试(name in submitted)平均 O(1),远快于列表搜索(O(n))。集合还自动防止重复条目。[2]
Student grades dictionary program.学生成绩字典程序。
The second assignment grades["Bob"] = 82 overwrites the first (= 78). Dictionary keys are unique; assigning to an existing key updates the value. Final: grades["Bob"] = 82. [2]第二次赋值 grades["Bob"] = 82 覆盖了第一次(= 78)。字典键是唯一的;对已有键赋值会更新其值。最终:grades["Bob"] = 82。[2]
| name姓名 | score成绩 | score ≥ 85?成绩 ≥ 85? | printed?是否打印? |
|---|---|---|---|
| Alice | 91 | Yes | Yes |
| Bob | 82 | No | No |
| Carol | 85 | Yes | Yes |
Output (one per line): Alice then Carol. [3]输出(每行一个):Alice 然后 Carol。[3]
A dictionary uses a hash table internally, so lookup by key is O(1) on average, whereas searching a list for a specific value requires checking each element sequentially, which is O(n). [1]字典内部使用哈希表,因此按键查找平均为 O(1),而在列表中搜索特定值需要逐个检查每个元素,时间复杂度为 O(n)。[1]
grades["Dave"] = 70
[1]
A list would be less suitable: to find Bob's grade you must scan every element (O(n) linear search), and there is no natural way to label entries by name without maintaining a parallel name-list. [1]列表较不适合:要找到 Bob 的成绩需要扫描每个元素(O(n) 线性搜索),且在不维护并行姓名列表的情况下无法自然地按姓名标记条目。[1]
counts[word] += 1 where we want to update, not duplicate.覆盖键是最常见的字典误解。Python 中字典不可能有重复键:第二次赋值会悄悄覆盖第一次。这是有意设计的行为,用于 counts[word] += 1 等更新而非重复添加的模式。Tuples and sets programs.元组与集合程序。
point = (3, 7). print(point[0]) outputs 3. The commented-out line point[0] = 5 would raise a TypeError: 'tuple' object does not support item assignment because tuples are immutable -- once created, elements cannot be reassigned. [2]point = (3, 7)。print(point[0]) 输出 3。被注释掉的行 point[0] = 5 若取消注释会引发 TypeError: 'tuple' object does not support item assignment,因为元组是不可变的——创建后元素不能被重新赋值。[2]
Input list: [85, 90, 85, 74, 90, 65]. Converting to set removes duplicates: {65, 74, 85, 90} (4 unique values). Duplicates removed: 85 (appeared at positions 0 and 2) and 90 (appeared at positions 1 and 4). [1]输入列表:[85, 90, 85, 74, 90, 65]。转换为集合去除重复:{65, 74, 85, 90}(4 个唯一值)。被删除的重复项:85(出现在位置 0 和 2)和 90(出现在位置 1 和 4)。[1]
print(len(unique)) outputs 4. print(85 in unique) outputs True. [2]print(len(unique)) 输出 4。print(85 in unique) 输出 True。[2]
Use a tuple when the data is a fixed, related group that must not change -- for example, storing a GPS location (53.546, -113.485) for Edmonton: the coordinates are fixed, and using a tuple prevents accidental modification. [1]当数据是不应改变的固定相关组时使用元组——例如,存储埃德蒙顿的 GPS 位置 (53.546, -113.485):坐标固定,使用元组可防止意外修改。[1]
a, b = b, a in Program A uses tuple unpacking for a swap -- a common Python idiom the SG Worked Example 6 covers. Set creation from a list is the fastest way to count distinct values: len(set(lst)).元组的关键区别属性是不可变性。因为不能改变,它们可以用作字典键(列表不能)。程序 A 中的 a, b = b, a 使用元组解包进行交换——学习指南例题 6 涵盖的常见 Python 惯用法。从列表创建集合是计算不同值数量最快的方式:len(set(lst))。Maximum-finding and filter operations on scores = [72, 45, 88, 61, 95, 38, 77].对 scores = [72, 45, 88, 61, 95, 38, 77] 进行求最大值和过滤操作。
Initial: max_val = scores[0] = 72. Loop starts at i=1.初始:max_val = scores[0] = 72。循环从 i=1 开始。
i | scores[i] | scores[i] > max_val?scores[i] > max_val? | max_val |
|---|---|---|---|
| 1 | 45 | No | 72 |
| 2 | 88 | Yes | 88 |
| 3 | 61 | No | 88 |
| 4 | 95 | Yes | 95 |
| 5 | 38 | No | 95 |
| 6 | 77 | No | 95 |
Final max_val = 95. [3]最终 max_val = 95。[3]
Elements >= 60: 72 (yes), 45 (no), 88 (yes), 61 (yes), 95 (yes), 38 (no), 77 (yes). passing = [72, 88, 61, 95, 77]. [2]大于等于 60 的元素:72(是)、45(否)、88(是)、61(是)、95(是)、38(否)、77(是)。passing = [72, 88, 61, 95, 77]。[2]
The loop starts at index 1 because max_val is initialised to scores[0] (the first element) before the loop begins. Starting at 0 would compare the first element against itself, which is redundant. Beginning at 1 means every element is compared against the current maximum exactly once. [2]循环从索引 1 开始,因为 max_val 在循环开始前已被初始化为 scores[0](第一个元素)。从 0 开始会将第一个元素与自身比较,这是多余的。从 1 开始意味着每个元素恰好与当前最大值比较一次。[2]
len(passing) = 5; len(scores) = 7. [1]len(passing) = 5;len(scores) = 7。[1]
2D grades array and nested loop traversal.二维成绩数组和嵌套循环遍历。
grades[1] selects row 1 (0-indexed): [72, 88, 94]. grades[1][2] selects element at column 2: 94. This refers to student 1 (the second student, 0-indexed) and test 2 (the third test, 0-indexed). [2]grades[1] 选择第 1 行(从零开始):[72, 88, 94]。grades[1][2] 选择第 2 列的元素:94。这对应学生 1(第二位学生,从零开始)和测试 2(第三次测试,从零开始)。[2]
| Row行 | Row contents行内容 | Row sum行和 | Running total累计 total |
|---|---|---|---|
| 0 | [85, 90, 78] | 253 | 253 |
| 1 | [72, 88, 94] | 254 | 507 |
| 2 | [91, 67, 83] | 241 | 748 |
Final total = 748. print(grades[1][2]) outputs 94. [3]最终 total = 748。print(grades[1][2]) 输出 94。[3]
total2 = 0
for row in grades:
total2 += row[0] + row[1]
This replaces the inner for score in row loop with direct index access to columns 0 and 1, skipping column 2. [2]这将内层 for score in row 循环替换为直接索引访问第 0 和第 1 列,跳过第 2 列。[2]
3 rows x 3 columns = 9 times. [1]3 行 x 3 列 = 9 次。[1]
grid[row][col] -- row first. The total number of inner-loop executions for an m x n grid is m x n. Ontario ICS4U A3.5 lists pixel processing as the canonical use case: a greyscale image is a 2D array of integers 0-255, and every filter traverses it with nested loops.二维数组访问始终是 grid[行][列]——先行后列。m x n 网格内层循环的总执行次数为 m x n。安大略 ICS4U A3.5 将像素处理列为典型用例:灰度图像是 0-255 整数的二维数组,每个滤镜都通过嵌套循环遍历它。Word frequency dictionary and set intersection on two sentences.两个句子的词频字典和集合交集。
sentence1.split() produces: ["the", "cat", "sat", "on", "the", "mat"] (6 words).sentence1.split() 产生:["the", "cat", "sat", "on", "the", "mat"](6 个单词)。
| word单词 | action操作 | counts after操作后 counts |
|---|---|---|
| "the" | not in counts -> set 1 | {"the":1} |
| "cat" | not in counts -> set 1 | {"the":1,"cat":1} |
| "sat" | not in counts -> set 1 | {"the":1,"cat":1,"sat":1} |
| "on" | not in counts -> set 1 | {"the":1,"cat":1,"sat":1,"on":1} |
| "the" | in counts -> += 1 | {"the":2,"cat":1,"sat":1,"on":1} |
| "mat" | not in counts -> set 1 | {"the":2,"cat":1,"sat":1,"on":1,"mat":1} |
Final counts = {"the": 2, "cat": 1, "sat": 1, "on": 1, "mat": 1}. [3]最终 counts = {"the": 2, "cat": 1, "sat": 1, "on": 1, "mat": 1}。[3]
set1 = {"the", "cat", "sat", "on", "mat"} (5 unique words from sentence1).set1 = {"the", "cat", "sat", "on", "mat"}(sentence1 中 5 个唯一单词)。
set2 = {"the", "dog", "sat", "by", "tree"} (5 unique words from sentence2).set2 = {"the", "dog", "sat", "by", "tree"}(sentence2 中 5 个唯一单词)。
common = set1 & set2 = {"the", "sat"}. These are the only words appearing in both sentences. [3]common = set1 & set2 = {"the", "sat"}。这两个单词是两个句子中共同出现的。[3]
len(words1) = 6 but len(set1) = 5 because the word "the" appears twice in sentence1, and sets automatically eliminate duplicates, keeping only one copy of each unique value. [1]len(words1) = 6 但 len(set1) = 5,因为单词 "the" 在 sentence1 中出现两次,而集合自动消除重复,每个唯一值只保留一份。[1]
The & operator computes the intersection of two sets -- it returns a new set containing only elements that appear in both sets. [1]& 运算符计算两个集合的交集——返回一个新集合,仅包含两个集合中都出现的元素。[1]
if word in counts: counts[word] += 1 else: counts[word] = 1) is the canonical dictionary-building algorithm. In Python 3.x you can shorten it using collections.Counter, but the manual version is what exams test. The three set operators to memorise: & intersection, | union, - difference (A minus B = elements in A not in B).词频字典模式(if word in counts: counts[word] += 1 else: counts[word] = 1)是典型的字典构建算法。在 Python 3.x 中可用 collections.Counter 简化,但考试测查的是手动版本。需记住的三个集合运算符:& 交集,| 并集,- 差集(A 减 B = A 中不在 B 里的元素)。Weather station temperatures [14, 19, 22, 18, 25, 21, 17], threshold 20.气象站气温 [14, 19, 22, 18, 25, 21, 17],阈值 20。
total = 14 + 19 + 22 + 18 + 25 + 21 + 17 = 136. average = 136 / 7 = 19.428... (approximately 19.43). [2]total = 14 + 19 + 22 + 18 + 25 + 21 + 17 = 136。average = 136 / 7 = 19.428...(约 19.43)。[2]
i | temps[i] | temps[i] > 20?temps[i] > 20? |
|---|---|---|
| 0 | 14 | No |
| 1 | 19 | No |
| 2 | 22 | Yes -- break |
found_index = 2. The temperature that triggered the break is 22 (day at index 2). [3]found_index = 2。触发 break 的气温是 22(索引 2 处的那天)。[3]
No temperature in temps exceeds 30 (the maximum is 25). The loop runs all 7 iterations without executing the if body, so found_index remains -1 (the sentinel value indicating "not found"). [2]temps 中没有气温超过 30(最大值为 25)。循环运行所有 7 次迭代而不执行 if 体,因此 found_index 保持 -1(表示"未找到"的哨兵值)。[2]
Last valid index = len(temps) - 1 = 7 - 1 = 6. Value at index 6: 17. [1]最后有效索引 = len(temps) - 1 = 7 - 1 = 6。索引 6 处的值:17。[1]
str.find() returns -1 when the substring is absent). On an exam, always initialise the result variable to a sentinel before the loop so that the loop only updates it when the condition is met. If the loop ends without a match, the sentinel survives as the answer.用 -1 作为"未找到"的哨兵是行业惯例(Python 的 str.find() 在子字符串不存在时返回 -1)。考试中,始终在循环前将结果变量初始化为哨兵值,这样循环只在条件满足时才更新它。若循环结束时没有匹配,哨兵值就是答案。Library book tracking with list and dictionary.使用列表和字典的图书馆书籍跟踪。
| Operation操作 | checked_out after操作后 checked_out |
|---|---|
| append("Python Basics") | ["Python Basics"] |
| append("Data Science") | ["Python Basics", "Data Science"] |
| insert(1, "Algorithms") | ["Python Basics", "Algorithms", "Data Science"] |
| remove("Data Science") | ["Python Basics", "Algorithms"] |
Final: ["Python Basics", "Algorithms"]. [2]最终:["Python Basics", "Algorithms"]。[2]
for name, books in borrowers.items():
if "Python Basics" in books:
print(name)
Output: Maya then Leon (both have "Python Basics" in their lists). [3]输出:Maya 然后 Leon(两人的列表中都有 "Python Basics")。[3]
borrowers["Maya"].remove("Algorithms")
This accesses Maya's list via the dictionary key and calls remove() on that list in place. [2]这通过字典键访问 Maya 的列表,并就地对该列表调用 remove()。[2]
A dictionary gives O(1) lookup by student name using a hash table, whereas two parallel lists require scanning the name list sequentially (O(n)) to find the matching index, then accessing the second list at that index. [2]字典通过哈希表按学生姓名提供 O(1) 查找,而两个并行列表需要顺序扫描姓名列表(O(n))来找到匹配索引,再从第二个列表访问该索引。[2]
dict[key].method() accesses the inner list directly. Ontario ICS4U C1.1 names this as an Abstract Data Type application; AB CSE2120 outcome 1.2.1 calls the simpler version "parallel arrays (associative tables)."嵌套数据结构(值为列表的字典)在实际程序和 ICS4U / AP CSA 级别中很常见。模式 dict[key].method() 直接访问内层列表。安大略 ICS4U C1.1 将此列为抽象数据类型应用;AB CSE2120 结果 1.2.1 将简化版本称为"并行数组(关联表)"。Social media set operations and tag frequency dictionary.社交媒体集合运算和标签频率字典。
followsA = {"alice", "bob", "carol", "dave"}. followsB = {"bob", "eve", "carol", "frank"}.followsA = {"alice", "bob", "carol", "dave"}。followsB = {"bob", "eve", "carol", "frank"}。
(i) Users followed by both: followsA & followsB = {"bob", "carol"}. These appear in both sets. [1](i) 两人都关注的用户:followsA & followsB = {"bob", "carol"}。这两个出现在两个集合中。[1]
(ii) Users followed only by A: followsA - followsB = {"alice", "dave"}. These appear in A but not in B. [2](ii) 只有 A 关注的用户:followsA - followsB = {"alice", "dave"}。这些出现在 A 中但不在 B 中。[2]
tags = ["#python", "#cs", "#python", "#data", "#cs", "#python"].tags = ["#python", "#cs", "#python", "#data", "#cs", "#python"]。
| tag标签 | in tag_counts?在 tag_counts 中? | tag_counts after操作后 tag_counts |
|---|---|---|
| #python | No -> set 1 | {"#python":1} |
| #cs | No -> set 1 | {"#python":1,"#cs":1} |
| #python | Yes -> +=1 | {"#python":2,"#cs":1} |
| #data | No -> set 1 | {"#python":2,"#cs":1,"#data":1} |
| #cs | Yes -> +=1 | {"#python":2,"#cs":2,"#data":1} |
| #python | Yes -> +=1 | {"#python":3,"#cs":2,"#data":1} |
Final: {"#python": 3, "#cs": 2, "#data": 1}. [3]最终:{"#python": 3, "#cs": 2, "#data": 1}。[3]
followsA and followsB are sets. The property that makes sets ideal for computing users-in-common is that the & intersection operator is built in and runs in average O(min(|A|, |B|)) time, far faster than any list-based approach. [2]followsA 和 followsB 是集合。使集合特别适合计算共同用户的属性是:内置的 & 交集运算符平均运行时间为 O(min(|A|, |B|)),远快于任何基于列表的方法。[2]
- is the structure-selection differentiator on CSTA 3B-AP-12 exams: "elements in A that are not in B" is a one-liner with sets (A - B) but requires a nested loop with lists (O(n^2)). Whenever a question mentions "unique membership" or "elements in common," reach for a set. The tag-count pattern mirrors the word-frequency pattern from Q9, confirming that dictionaries are the canonical tool for any "count occurrences" problem.集合差集运算符 - 是 CSTA 3B-AP-12 考试中的结构选择区分点:"A 中不在 B 里的元素"用集合是一行代码(A - B),而用列表需要嵌套循环(O(n^2))。每当问题提到"唯一成员"或"共同元素"时,选择集合。标签计数模式与 Q9 的词频模式相同,证实字典是任何"统计出现次数"问题的典型工具。