Companion to the Practice Set · Mark-by-mark walkthroughs · AP CSP-Feeder / US / ON / BC / AB styles练习题配套详解 · 逐分讲解 · AP CSP 衔接 / 美 / 安 / 卑 / 阿省考风格
Linear search on [11, 4, 27, 9, 15, 3, 22] for target 15. How many comparisons?对 [11, 4, 27, 9, 15, 3, 22] 线性查找目标 15。共几次比较?
Trace each index in order: [2]按顺序追踪每个索引:[2]
data[0] = 11, 11 != 15. Continue.data[0] = 11,11 != 15。继续。data[1] = 4, 4 != 15. Continue.data[1] = 4,4 != 15。继续。data[2] = 27, 27 != 15. Continue.data[2] = 27,27 != 15。继续。data[3] = 9, 9 != 15. Continue.data[3] = 9,9 != 15。继续。data[4] = 15, 15 == 15. FOUND. That is the 5th comparison. [1]data[4] = 15,15 == 15。找到。这是第 5 次比较。[1]Which list can binary search be applied to correctly without modification?哪个列表可以正确地直接应用二分查找而无需任何修改?
Binary search requires the list to be sorted in ascending order. Evaluate each option: [2]二分查找要求列表按升序排列。评估每个选项:[2]
[8, 3, 12, 1, 19] -- unsorted. Binary search would give wrong results.[8, 3, 12, 1, 19] -- 无序。二分查找会给出错误结果。[19, 12, 8, 3, 1] -- sorted descending, not ascending. Binary search needs ascending order.[19, 12, 8, 3, 1] -- 降序排列,非升序。二分查找需要升序。[1, 3, 8, 12, 19] -- sorted ascending. Binary search applies correctly. [1][1, 3, 8, 12, 19] -- 升序排列。二分查找可正确应用。[1][1, 8, 3, 12, 19] -- partially unsorted (8 > 3). Binary search would incorrectly eliminate halves.[1, 8, 3, 12, 19] -- 部分无序(8 > 3)。二分查找会错误地淘汰某些部分。Linear search on [6, 14, 2, 31, 8, 20] for target 31.对 [6, 14, 2, 31, 8, 20] 线性查找目标 31。
| i | data[i] | data[i] == 31?data[i] == 31? | Action操作 |
|---|---|---|---|
| 0 | 6 | False | continue继续 |
| 1 | 14 | False | continue继续 |
| 2 | 2 | False | continue继续 |
| 3 | 31 | True | found = True, OUTPUT 3, STOPfound = True,输出 3,停止 |
Award 1 mark per correct row up to 3 rows. [3]每行正确得 1 分,最多 3 行。[3]
Part (b):第 (b) 部分: The program outputs 3 (the index where 31 was found). [1]程序输出 3(找到 31 的索引)。[1]
Part (c):第 (c) 部分: If target = 99, the program outputs -1. The loop runs all 6 iterations without finding 99, so found remains False and the final IF outputs -1. [1]若目标为 99,程序输出 -1。循环运行全部 6 次迭代未找到 99,因此 found 仍为 False,最后的 IF 输出 -1。[1]
Big-O classifications and step counts for n = 64.大O分类及 n = 64 时的步骤数。
| Algorithm算法 | Big-O (worst)大O(最坏) | Steps at n = 64n = 64 时步骤数 |
|---|---|---|
| Linear search线性查找 | O(n) | 64 |
| Binary search二分查找 | O(log n) | 6 |
| Bubble sort冒泡排序 | O(n²) | 2016 |
Binary search log row: log₂(64) = 6 because 2⁶ = 64. [1]二分查找 log 行:log₂(64) = 6,因为 2⁶ = 64。[1]
Bubble sort: n(n-1)/2 = 64 x 63 / 2 = 2016. [1]冒泡排序:n(n-1)/2 = 64 x 63 / 2 = 2016。[1]
Cost of binary search's sorted requirement: sorting takes at least O(n log n) time (or O(n²) for simple sorts), which must be paid upfront before any binary search can run. If only one search is needed, this overhead can make binary search more expensive overall than repeated linear search. [2]二分查找已排序要求的代价:排序至少需要 O(n log n) 时间(简单排序为 O(n²)),这必须在任何二分查找运行之前预先支付。若只需一次查找,这种开销可能使二分查找整体比反复线性查找更昂贵。[2]
Part (b):第 (b) 部分: n = 2²⁰ = 1,048,576. Binary search worst case = log₂(2²⁰) = 20 comparisons. [2]n = 2²⁰ = 1,048,576。二分查找最坏情况 = log₂(2²⁰) = 20 次比较。[2]
Bubble sort on [7, 2, 9, 4, 6].对 [7, 2, 9, 4, 6] 冒泡排序。
Working through each pass (compare adjacent pairs, swap if left > right): [4]逐遍处理(比较相邻元素,若左 > 右则交换):[4]
| Pass遍 | List after pass该遍后列表 | Swaps this pass本遍交换次数 |
|---|---|---|
| Start初始 | [7, 2, 9, 4, 6] | -- |
| 1 | [2, 7, 4, 6, 9] | 3 |
| 2 | [2, 4, 6, 7, 9] | 2 |
| 3 | [2, 4, 6, 7, 9] | 0 |
| 4 | [2, 4, 6, 7, 9] | 0 |
(7,2): 7>2, swap → [2,7,9,4,6]. (7,9): 7<9, no swap. (9,4): 9>4, swap → [2,7,4,9,6]. (9,6): 9>6, swap → [2,7,4,6,9]. 3 swaps.(7,2):7>2,交换 → [2,7,9,4,6]。(7,9):7<9,不交换。(9,4):9>4,交换 → [2,7,4,9,6]。(9,6):9>6,交换 → [2,7,4,6,9]。共 3 次交换。
(2,7): no swap. (7,4): 7>4, swap → [2,4,7,6,9]. (7,6): 7>6, swap → [2,4,6,7,9]. (9 is already placed, boundary shrinks). 2 swaps.(2,7):不交换。(7,4):7>4,交换 → [2,4,7,6,9]。(7,6):7>6,交换 → [2,4,6,7,9]。(9 已就位,边界缩小)。2 次交换。
Part (b):第 (b) 部分: Total swaps = 3 + 2 + 0 + 0 = 5. [1]交换总次数 = 3 + 2 + 0 + 0 = 5。[1]
Part (c):第 (c) 部分: After pass 1, element 9 is guaranteed to be in its final position (index 4). Bubble sort moves the largest unsorted element to the rightmost unsorted position in each pass. After pass 1, 9 is the largest element and has "bubbled up" to index 4. [2]第 1 遍后,元素 9 一定处于最终位置(索引 4)。冒泡排序每遍将最大的未排序元素移至最右侧未排序位置。第 1 遍后,9 是最大元素,已"冒泡"到索引 4。[2]
Part (d):第 (d) 部分: Worst-case Big-O: O(n²). [1]最坏情况大O复杂度:O(n²)。[1]
swapped flag and a full pass makes 0 swaps, the list is already sorted and the algorithm terminates early. This gives O(n) best-case performance on already-sorted input.无交换的遍次是提前退出信号:若优化版冒泡排序追踪 swapped 标志,且某遍完成 0 次交换,则列表已排好,算法提前终止。这使已排序输入的最好情况性能达到 O(n)。Binary search on [2, 5, 9, 14, 21, 33, 40, 58] (indices 0-7) for target 21.对 [2, 5, 9, 14, 21, 33, 40, 58](索引 0-7)二分查找目标 21。
| Step步骤 | low | high | mid | data[mid] | Action操作 |
|---|---|---|---|---|---|
| 1 | 0 | 7 | 3 | 14 | 14 < 21, low = 414 < 21,low = 4 |
| 2 | 4 | 7 | 5 | 33 | 33 > 21, high = 433 > 21,high = 4 |
| 3 | 4 | 4 | 4 | 21 | 21 == 21, FOUND at index 421 == 21,在索引 4 处找到 |
Step 1: mid = (0+7)//2 = 3, data[3] = 14. 14 < 21 so low = 4. Step 2: mid = (4+7)//2 = 5, data[5] = 33. 33 > 21 so high = 4. Step 3: mid = (4+4)//2 = 4, data[4] = 21. Match. [4]第 1 步:mid = (0+7)//2 = 3,data[3] = 14。14 < 21,low = 4。第 2 步:mid = (4+7)//2 = 5,data[5] = 33。33 > 21,high = 4。第 3 步:mid = (4+4)//2 = 4,data[4] = 21。匹配。[4]
Part (b):第 (b) 部分: Binary search needed 3 comparisons. Linear search worst case on an 8-element list = 8 comparisons (if target is last or not present). [2]二分查找需要 3 次比较。线性查找在 8 元素列表上的最坏情况 = 8 次比较(目标在最后或不存在时)。[2]
Part (c):第 (c) 部分: Binary search returns -1. When low > high, the search space is exhausted without finding the target -- the algorithm exits the WHILE loop and returns the sentinel value -1 to signal "not found." [1]二分查找返回 -1。当 low > high 时,搜索空间耗尽仍未找到目标--算法退出 WHILE 循环并返回哨兵值 -1 以示"未找到"。[1]
Selection sort on [8, 3, 11, 1, 6].对 [8, 3, 11, 1, 6] 选择排序。
| Pass (i)遍(i) | Min found (value, idx)找到最小值(值,索引) | List after swap交换后列表 |
|---|---|---|
| Start初始 | -- | [8, 3, 11, 1, 6] |
| 0 | 1, idx 3 | [1, 3, 11, 8, 6] |
| 1 | 3, idx 1 | [1, 3, 11, 8, 6] |
| 2 | 6, idx 4 | [1, 3, 6, 8, 11] |
| 3 | 8, idx 3 | [1, 3, 6, 8, 11] |
Pass i=0: scan indices 0-4, min = 1 at idx 3. Swap data[0] and data[3] → [1, 3, 11, 8, 6].第 i=0 遍:扫描索引 0-4,最小值 = 1 在 idx 3。交换 data[0] 和 data[3] → [1, 3, 11, 8, 6]。
Pass i=1: scan indices 1-4, min = 3 at idx 1. Swap data[1] with itself (no change).第 i=1 遍:扫描索引 1-4,最小值 = 3 在 idx 1。data[1] 与自身交换(无变化)。
Pass i=2: scan indices 2-4, min = 6 at idx 4. Swap data[2] and data[4] → [1, 3, 6, 8, 11].第 i=2 遍:扫描索引 2-4,最小值 = 6 在 idx 4。交换 data[2] 和 data[4] → [1, 3, 6, 8, 11]。
Pass i=3: scan indices 3-4, min = 8 at idx 3. Swap data[3] with itself (no change). [4]第 i=3 遍:扫描索引 3-4,最小值 = 8 在 idx 3。data[3] 与自身交换(无变化)。[4]
Part (b):第 (b) 部分: Selection sort performs n-1 = 4 swap operations (even if some swap an element with itself). Meaningful position changes: 2 (passes i=0 and i=2). Bubble sort worst case on a 5-element list = (5-1)+(5-2)+(5-3)+(5-4) = 4+3+2+1 = 10 swaps. Selection sort's at most 4 (n-1) swaps vs bubble sort's up to 10: selection sort makes far fewer writes. [2]选择排序执行 n-1 = 4 次交换操作(即使某些交换是元素与自身交换)。实际位置变化:2 次(第 i=0 和 i=2 遍)。冒泡排序在 5 元素列表上最坏情况 = 4+3+2+1 = 10 次交换。选择排序最多 4(n-1)次交换 vs 冒泡排序最多 10 次:选择排序写入次数少得多。[2]
Part (c):第 (c) 部分: After pass i=2, 3 elements are in their final sorted positions: the 3 smallest elements 1, 3, 6 are now at indices 0, 1, 2 respectively and will not move again. In general, after pass i=k, elements at indices 0 through k are finalized. [2]第 i=2 遍后,3 个元素处于最终排序位置:3 个最小元素 1、3、6 现在分别在索引 0、1、2 处,不会再移动。一般规律:第 i=k 遍后,索引 0 到 k 处的元素已最终确定。[2]
Insertion sort on [6, 2, 10, 4, 8].对 [6, 2, 10, 4, 8] 插入排序。
| i | key | Shifts移位次数 | List after insertion插入后列表 |
|---|---|---|---|
| Start初始 | -- | -- | [6, 2, 10, 4, 8] |
| 1 | 2 | 1 | [2, 6, 10, 4, 8] |
| 2 | 10 | 0 | [2, 6, 10, 4, 8] |
| 3 | 4 | 2 | [2, 4, 6, 10, 8] |
| 4 | 8 | 1 | [2, 4, 6, 8, 10] |
i=1, key=2: j=0, data[0]=6>2, shift data[0] right → [6,6,10,4,8], j=-1 (stop), insert at idx 0 → [2,6,10,4,8]. 1 shift.i=1,key=2:j=0,data[0]=6>2,右移 data[0] → [6,6,10,4,8],j=-1(停止),插入到 idx 0 → [2,6,10,4,8]。1 次移位。
i=2, key=10: j=1, data[1]=6, 6 < 10 (WHILE condition false immediately). Insert at idx 2. 0 shifts.i=2,key=10:j=1,data[1]=6,6 < 10(WHILE 条件立即为假)。插入到 idx 2。0 次移位。
i=3, key=4: j=2, data[2]=10>4, shift → [...,10,10,8], j=1, data[1]=6>4, shift → [...,6,10,8], j=0, data[0]=2, 2 < 4 (stop), insert at idx 1 → [2,4,6,10,8]. 2 shifts.i=3,key=4:j=2,data[2]=10>4,移位 → [...,10,10,8],j=1,data[1]=6>4,移位 → [...,6,10,8],j=0,data[0]=2,2 < 4(停止),插入到 idx 1 → [2,4,6,10,8]。2 次移位。
i=4, key=8: j=3, data[3]=10>8, shift → [...,10,10], j=2, data[2]=6, 6 < 8 (stop), insert at idx 3 → [2,4,6,8,10]. 1 shift. [4]i=4,key=8:j=3,data[3]=10>8,移位 → [...,10,10],j=2,data[2]=6,6 < 8(停止),插入到 idx 3 → [2,4,6,8,10]。1 次移位。[4]
Part (b):第 (b) 部分: Total shifts = 1 + 0 + 2 + 1 = 4. [1]移位总次数 = 1 + 0 + 2 + 1 = 4。[1]
Part (c):第 (c) 部分: When the input is nearly sorted, most elements are already in roughly the right position. The WHILE loop condition data[j] > key becomes False almost immediately for each i -- requiring 0 or 1 shifts per element instead of many. Total work approaches O(n): one comparison per element. Bubble and selection sort do not benefit from nearly-sorted input in the same way: selection sort always scans the entire remaining unsorted portion for the minimum, and basic bubble sort always performs all n-1 passes. [2]当输入已近乎有序时,大多数元素已大致处于正确位置。每个 i 的 WHILE 循环条件 data[j] > key 几乎立即为 False--每个元素只需 0 或 1 次移位而非多次。总工作量趋近 O(n):每个元素一次比较。冒泡和选择排序不能以同样方式受益于近乎有序的输入:选择排序总是扫描整个剩余未排序部分寻找最小值,基本冒泡排序总是执行全部 n-1 遍。[2]
Part (d):第 (d) 部分: Best case: O(n) -- when the list is already sorted in ascending order (the WHILE loop never executes, just one comparison per element). Worst case: O(n²) -- when the list is in reverse descending order (every element must shift all the way to index 0). [1]最好情况:O(n)--当列表已按升序排列时(WHILE 循环从不执行,每个元素只需一次比较)。最坏情况:O(n²)--当列表完全逆序时(每个元素都需一路移位到索引 0)。[1]
n = 1,000,000 records. Option 1: 10 linear searches. Option 2: O(n²) sort + 10 binary searches. log₂(1,000,000) = 20.n = 1,000,000 条记录。方案 1:10 次线性查找。方案 2:O(n²) 排序 + 10 次二分查找。log₂(1,000,000) = 20。
Part (a):第 (a) 部分: Option 1 total = 10 x 1,000,000 = 10,000,000 worst-case comparisons. [1]方案 1 总计 = 10 x 1,000,000 = 10,000,000 次最坏情况比较。[1]
Part (b):第 (b) 部分: Option 2 sort cost (O(n²)) = (1,000,000)² = 10¹² = 1,000,000,000,000 steps. Binary searches = 10 x 20 = 200 steps. Total = 10¹² + 200 steps, which is dominated by the sort. [2]方案 2 排序代价(O(n²))= (1,000,000)² = 10¹² = 1,000,000,000,000 步。二分查找 = 10 x 20 = 200 步。总计 = 10¹² + 200 步,由排序主导。[2]
Part (c):第 (c) 部分: For 10 searches: Option 1 (10,000,000) is dramatically better than Option 2 with O(n²) sort (10¹²). The sort cost swamps any gain from binary search. For 1,000 searches: Option 1 = 1,000 x 1,000,000 = 10⁹ steps. Option 2 = 10¹² + 1,000 x 20 = 10¹² + 20,000 steps -- still dominated by 10¹², so Option 1 is still better when using a simple O(n²) sort. [2]对于 10 次查找:方案 1(10,000,000)远优于带 O(n²) 排序的方案 2(10¹²)。排序代价淹没了二分查找的收益。对于 1,000 次查找:方案 1 = 1,000 x 1,000,000 = 10⁹ 步。方案 2 = 10¹² + 1,000 x 20 = 10¹² + 20,000 步--仍由 10¹² 主导,使用简单 O(n²) 排序时方案 1 仍然更好。[2]
Part (d):第 (d) 部分: Timsort cost = 1,000,000 x 20 = 20,000,000 steps. Plus 10 binary searches = 200. Total = 20,000,200 steps. Compared to linear search Option 1 = 10,000,000 steps. For exactly 10 searches, linear search is still slightly cheaper (10,000,000 vs 20,000,200). However, the crossover point with Timsort is approximately 20,000,000 / 1,000,000 = 20 searches -- so for more than 20 searches on this dataset, Timsort + binary search wins. For 1,000 searches: Option 1 = 10⁹; Option 2 with Timsort = 20,000,000 + 20,000 = 20,020,000 -- Option 2 wins by ~50x. [2]Timsort 代价 = 1,000,000 x 20 = 20,000,000 步。加上 10 次二分查找 = 200 步。总计 = 20,000,200 步。与线性查找方案 1 = 10,000,000 步相比。对于恰好 10 次查找,线性查找仍略便宜(10,000,000 vs 20,000,200)。但是,使用 Timsort 的临界点约为 20,000,000 / 1,000,000 = 20 次查找--所以超过 20 次查找时,Timsort + 二分查找胜出。对于 1,000 次查找:方案 1 = 10⁹;带 Timsort 的方案 2 = 20,000,000 + 20,000 = 20,020,000--方案 2 胜出约 50 倍。[2]
Scenario A: unsorted [23, 47, 8, 61, 15, 39, 72]. Scenario B: sorted [8, 15, 23, 39, 47, 61, 72]. Target: 47.场景 A:无序 [23, 47, 8, 61, 15, 39, 72]。场景 B:有序 [8, 15, 23, 39, 47, 61, 72]。目标:47。
Linear search must be used because the list is unsorted. Binary search requires a sorted list as a precondition; applying it to an unsorted list can eliminate the correct half. [1]必须使用线性查找,因为列表无序。二分查找要求已排序列表作为前提条件;在无序列表上应用会淘汰正确的一半。[1]
Trace: index 0: 23 != 47. Index 1: 47 == 47. FOUND. Indices checked: 0, 1. Total comparisons: 2. [2]追踪:索引 0:23 != 47。索引 1:47 == 47。找到。检查的索引:0、1。总比较次数:2。[2]
| Step步骤 | low | high | mid | data[mid] | Action操作 |
|---|---|---|---|---|---|
| 1 | 0 | 6 | 3 | 39 | 39 < 47, low = 439 < 47,low = 4 |
| 2 | 4 | 6 | 5 | 61 | 61 > 47, high = 461 > 47,high = 4 |
| 3 | 4 | 4 | 4 | 47 | 47 == 47, FOUND at index 447 == 47,在索引 4 处找到 |
Step 1: mid=(0+6)//2=3, data[3]=39<47, low=4. Step 2: mid=(4+6)//2=5, data[5]=61>47, high=4. Step 3: mid=(4+4)//2=4, data[4]=47==47. FOUND. [3]第 1 步:mid=(0+6)//2=3,data[3]=39<47,low=4。第 2 步:mid=(4+6)//2=5,data[5]=61>47,high=4。第 3 步:mid=(4+4)//2=4,data[4]=47==47。找到。[3]
Part (c):第 (c) 部分: Scenario A (linear): 2 comparisons. Scenario B (binary): 3 comparisons. In this case linear was actually faster because the target happened to be near the start. Advantage of binary: O(log n) worst case vs O(n) worst case -- for large lists and targets near the end, binary is dramatically faster. Disadvantage: requires the list to be sorted in advance, which takes extra time and memory. [2]场景 A(线性):2 次比较。场景 B(二分):3 次比较。此例中线性查找实际更快,因为目标恰好靠近列表开头。二分查找的优势:最坏情况 O(log n) vs O(n)--对于大列表且目标靠近末尾时,二分查找快得多。缺点:需要列表提前已排序,这需要额外的时间和内存。[2]
Sort algorithm selection for three scenarios.三种场景的排序算法选择。
Best choice: Insertion sort. Insertion sort has O(n) best-case performance on already-sorted or nearly-sorted data -- the WHILE loop terminates almost immediately for each element since most are already in the correct relative order. Bubble sort and selection sort both always perform O(n²) work on this input (selection always scans the full unsorted portion; basic bubble always runs n-1 passes). [3]最佳选择:插入排序。插入排序在已排序或近乎有序数据上具有 O(n) 最好情况性能--由于大多数元素已基本处于正确的相对顺序,每个元素的 WHILE 循环几乎立即终止。冒泡排序和选择排序在此输入上均始终执行 O(n²) 工作(选择排序总是扫描完整未排序部分;基本冒泡排序总是运行 n-1 遍)。[3]
Bubble sort swaps冒泡排序交换次数: Pass 1: 6 swaps (every adjacent pair out of order). Pass 2: 5 swaps. Pass 3: 4. Pass 4: 3. Pass 5: 2. Pass 6: 1. Total = 6+5+4+3+2+1 = 21 swaps.:第 1 遍:6 次交换(每对相邻元素均乱序)。第 2 遍:5 次。第 3 遍:4 次。第 4 遍:3 次。第 5 遍:2 次。第 6 遍:1 次。总计 = 6+5+4+3+2+1 = 21 次交换。
Selection sort swaps选择排序交换次数: Exactly n-1 = 6 swaps (one per pass, regardless of order).:恰好 n-1 = 6 次交换(每遍一次,与顺序无关)。
Selection sort makes fewer swaps: 6 vs 21. Selection sort is the better choice when minimizing write operations. [4]选择排序交换次数更少:6 vs 21。当需要最小化写操作时,选择排序是更好的选择。[4]
Part (c):第 (c) 部分: Case where insertion sort is better than bubble sort: nearly-sorted input -- insertion sort runs in O(n) while bubble sort still runs O(n²) passes. Case where they perform identically in terms of swaps: an already-fully-sorted list -- both perform 0 swaps (insertion sort's WHILE loop never executes; optimised bubble sort's first pass makes 0 swaps and exits). [2]插入排序优于冒泡排序的情况:近乎有序输入--插入排序以 O(n) 运行,而冒泡排序仍执行 O(n²) 遍次。两者交换次数相同的情况:已完全排好的列表--两者均执行 0 次交换(插入排序的 WHILE 循环从不执行;优化版冒泡排序第一遍 0 次交换后退出)。[2]
students = [("Zara",88),("Alex",95),("Maya",73),("Ben",88),("Priya",91)]. Sort by score ascending, then linear search for score 88.students = [("Zara",88),("Alex",95),("Maya",73),("Ben",88),("Priya",91)]。按分数升序排序,然后线性查找分数 88。
students.sort(key=lambda s: s[1]) sorts by the second element (score) ascending. Python's sort is stable, so equal scores maintain their original relative order. Zara (88) appeared before Ben (88) in the original list. [2]students.sort(key=lambda s: s[1]) 按第二个元素(分数)升序排序。Python 的排序是稳定的,所以相同分数保持原来的相对顺序。Zara(88)在原始列表中出现在 Ben(88)之前。[2]
[("Maya", 73), ("Zara", 88), ("Ben", 88), ("Priya", 91), ("Alex", 95)]
Part (b):第 (b) 部分: Linear search for score 88: i=0: students[0] = ("Maya",73), 73 != 88. Continue. i=1: students[1] = ("Zara",88), 88 == 88. FOUND. Prints: Found: ('Zara', 88). Loop exits via break at i=1. [2]线性查找分数 88:i=0:students[0]=("Maya",73),73!=88。继续。i=1:students[1]=("Zara",88),88==88。找到。打印:Found: ('Zara', 88)。循环在 i=1 时通过 break 退出。[2]
Part (c):第 (c) 部分: Sort by score descending, name ascending as tiebreaker:按分数降序、姓名升序(作为次要排序键)排序:
students.sort(key=lambda s: (-s[1], s[0]))
The negation -s[1] reverses the score order (largest score sorts first). s[0] is the name; when scores tie, names sort ascending alphabetically. [2]取负 -s[1] 反转分数排序顺序(最高分排在最前)。s[0] 是姓名;当分数相同时,姓名按字母升序排列。[2]
Part (d):第 (d) 部分: students.sort(...) modifies the original list in place and returns None. sorted(students, ...) returns a new sorted list and leaves the original students unchanged. If you need to keep the original unsorted list, use sorted() because .sort() would permanently modify students and the original order would be lost. [2]students.sort(...) 原地修改原始列表并返回 None。sorted(students, ...) 返回新的排序列表,原始 students 不变。如果需要保留原始未排序列表,使用 sorted(),因为 .sort() 会永久修改 students,原始顺序将丢失。[2]
key=lambda s: (-s[1], s[0]) trick is a standard Python pattern for multi-key sorting with mixed sort directions. Tuple comparison in Python works left-to-right: first compare by -s[1] (negated score), and only if those are equal, compare by s[0] (name). This is exactly the pattern used in competitive programming and real applications for ranking leaderboards.key=lambda s: (-s[1], s[0]) 技巧是 Python 中混合排序方向多键排序的标准模式。Python 中的元组比较从左到右进行:先按 -s[1](取负的分数)比较,仅当相等时才按 s[0](姓名)比较。这正是在排行榜排名的竞赛编程和实际应用中使用的模式。