纠错建议 35 分钟学习等级 3/8

PYTHON LESSON 045

易错辨析:五个最常踩的坑

逐个击破三级最常犯的 5 个错误,做到看见错例能立刻说出错因和正确写法。

00 · 学习目标

这一课要解决什么?

先想一想为什么 ranked = scores.sort() 之后,打印出来的却是 None?
完成任务三级避坑指南
学习顺序观察错误 → 定位原因 → 最小修改 → 回归测试

学完后,你应该能够

  • sorted() 返回新列表,sort() 原地排序无返回
  • int(x, 2) 要求每位数字都小于 2
  • in 查字典看的是键;筛选 if 放解析末尾

01 · 核心概念

错例 → 报错/错因 → 正确写法

错例 → 报错/错因 → 正确写法:错例:ranked = scores.sort(),打印 ranked 得到 None。原因:sort() 是“原地排序”,它直接修改 scores 自己,不返回新列表。正确写法二选一:要新列表用 sorted(scores);要原地排就 scores.sort() 之后直接用 scores。这是三级选择题的“万年老坑”。

考级对应GESP Python 3 级 · 常用内置函数GESP Python 3 级 · 列表解析GESP Python 3 级 · 进制转换
学习边界

在线判题的学生代码由独立 Worker 执行;文件系统、网络和资源权限必须受平台限制。

02 · 语法与规则

先记住这 3 条,再开始写程序

01sorted() 返回新列表,sort() 原地排序无返回

先准确读出这条写法的结构与作用。

02int(x, 2) 要求每位数字都小于 2

换一组最小数据,手工推演一次结果。

03in 查字典看的是键;筛选 if 放解析末尾

再用边界值或反例确认它的适用条件。

03 · 完整实例

代码、运行结果和解释放在一起看

g3-common-pitfalls.pyPYTHON 3.12
# 易错辨析:五个最常踩的坑(只运行正确写法,错例写在注释里)

# 坑 1:sort() 没有返回值
scores = [76, 92, 85]
# 错例:ranked = scores.sort()  → ranked 是 None!
scores.sort(reverse=True)
print("坑 1 正确写法:", scores)

# 坑 2:int() 按二进制读字符串时,每位数字必须小于 2
# 错例:int("12", 2)  → ValueError,二进制里根本不存在数字 2
print("坑 2 正确写法:", int("11", 2))

# 坑 3:in 查字典,查的是键不是值
contacts = {"小明": "13800000001"}
# 错例:"13800000001" in contacts  → False,查不到!
print("坑 3 正确写法:", "小明" in contacts, "13800000001" in contacts.values())

# 坑 4:元组创建后不能修改
point = (3, 4)
# 错例:point[0] = 5  → TypeError
point = (5, point[1])
print("坑 4 正确写法:", point)

# 坑 5:列表解析里 if 的位置
nums = [3, -1, 4, -2]
# 只筛选:if 放在最后;要 if-else 分支:放在最前
positives = [x for x in nums if x > 0]
marks = [x if x > 0 else 0 for x in nums]
print("坑 5 正确写法:", positives, marks)
运行结果OUTPUT
坑 1 正确写法: [92, 85, 76]
坑 2 正确写法: 3
坑 3 正确写法: True True
坑 4 正确写法: (5, 4)
坑 5 正确写法: [3, 4] [3, 0, 4, 0]

每个坑的错例都写在注释里,取消注释运行就能看到真实的报错信息。

在新标签运行和修改这个实例已装入本课代码 · 可自定义输入 · 可提交判题

04 · 逐步理解

每一步只解决一个问题

  1. 01

    坑 1:sort() 的返回值是 None

    错例:ranked = scores.sort(),打印 ranked 得到 None。原因:sort() 是“原地排序”,它直接修改 scores 自己,不返回新列表。正确写法二选一:要新列表用 sorted(scores);要原地排就 scores.sort() 之后直接用 scores。这是三级选择题的“万年老坑”。

    PYTHON
    scores.sort(reverse=True)
    print(scores)
  2. 02

    坑 2:int() 读不了“假二进制”

    错例:int("12", 2) 直接报 ValueError。原因:二进制每位只能是 0 或 1,字符串里出现 2 就是“假二进制”。记忆法:每位数字必须小于进制——八进制不能有 8,十六进制可以有 f。读题时先检查输入合不合法。

    PYTHON
    print(int("11", 2))
  3. 03

    坑 3:in 查字典查的是键

    错例:"13800000001" in contacts 返回 False,明明号码就在里面!原因:in 对字典只看键,不看值。正确写法:查人名用 "小明" in contacts;查号码用 in contacts.values()。键和值一字之差,结果相反。

    PYTHON
    print("小明" in contacts)
    print("13800000001" in contacts.values())
  4. 04

    坑 4:元组是“焊死的”列表

    错例:point[0] = 5 报 TypeError。原因:元组创建后任何元素都不能改。真想“改”怎么办?造一个新元组:point = (5, point[1])——旧的不动,新的上岗。考试问“下列哪个操作合法”,看到给元组元素赋值就直接排除。

    PYTHON
    point = (5, point[1])
  5. 05

    坑 5:列表解析里 if 的位置

    错例:[x for x in nums if x > 0 else 0] 报 SyntaxError。规律:只筛选,if 放最后(后面不许跟 else);要分支,if-else 整体放最前。一句话记牢:“筛选靠后、分支靠前”。

    PYTHON
    positives = [x for x in nums if x > 0]
    marks = [x if x > 0 else 0 for x in nums]
  6. 06

    把错题本变成程序

    建议你也建一个自己的“踩坑合集”:每道错题写清错例、报错、原因、正确写法四行。考前翻一遍,比刷新题更提分。本课的 demo 就是模板,照着攒就行。

05 · 练习与检验

自己写出来,才算真正学会

本课实作步骤
  1. 1运行程序,看 5 个正确写法的输出
  2. 2把注释里的错例逐个放出来跑,记录报错信息
  3. 3合上书复述 5 个坑的错因
  4. 4做配套模拟题,自查有没有踩坑
打开本课编程实验室编辑、运行、测试、判题都在一个页面完成

06 · 完整知识

继续理解定义、规则和适用边界

第一次学习先完成上面的六个步骤;需要查定义、核对规则、分析误区或理解“为什么”时,再展开对应知识章。

工程能力异常、文件、测试与调试读懂报错、缩小问题、设计测试,并安全地打开、读取和关闭文本文件。

正式定义

异常是在运行期间表示错误或特殊情况的对象。调试是用可复现输入和证据定位实际行为与预期行为差异的过程;文件对象连接程序与持久化字节数据。

必须掌握

  • 先读 traceback 最后一行的异常类型与消息,再从最靠近自己代码的栈帧向上追踪。
  • try 只包可能失败的最小代码;except 捕获具体异常;else 处理成功路径;finally 做必需清理。
  • raise 主动报告不满足的前置条件;assert 用于开发期内部假设,不用于校验不可信用户输入。
  • with open(...) as file 会在退出代码块时可靠关闭文件。文本模式必须明确编码,本站统一推荐 encoding='utf-8'。
  • 测试至少包含正常值、边界值、空数据、极端值和反例;每个测试只应有明确目的。
  • 定位错误时一次只改一个假设,保留能稳定复现问题的最小输入。

OPEN MODES

文件打开模式速查

基本动作 r/w/x/a 与文本或二进制 t/b、更新标记 + 组合使用,例如 rb、w+。文本文件建议明确 encoding='utf-8'。

open() 常用文件模式
标记作用
r读取;文件必须存在
w写入;先清空已有文件,不存在则创建
x独占创建;已存在则报错
a追加;写入位置在文件末尾
t文本模式(默认)
b二进制模式,读写 bytes
+更新模式,同时允许读写;与 r/w/x/a 组合

常见误区

  • 使用 except: 吞掉所有错误
  • 只测题目样例就认为程序正确
  • 文本文件不写 encoding
  • 修复报错表象却不验证根因

适用边界

  • 在线判题的学生代码由独立 Worker 执行;文件系统、网络和资源权限必须受平台限制。
  • 二进制文件、JSON/CSV 和数据库各有专门格式与错误处理方式,不能按普通文本随意拆分。
打开本章完整示例与独立阅读页 →
核心数据结构列表、元组、字典与集合按顺序、可变性、唯一性和查找需求选择容器,并掌握遍历、推导式、排序与复制。

正式定义

容器保存多个对象。list 是可变有序序列,tuple 是不可变有序序列,dict 保存唯一键到值的映射,set 保存无序且不重复的可哈希对象。

必须掌握

  • list 支持下标、切片、append、extend、insert、pop、remove 与 sort;多数修改方法返回 None。
  • tuple 的逗号比括号更关键,单元素元组必须写成 (value,)。
  • dict 保持插入顺序;键必须可哈希且唯一,get 可提供缺省值,items 同时遍历键和值。
  • set 用于去重与集合运算:| 并、& 交、- 差、^ 对称差;空集合必须写 set()。
  • enumerate 同时给出序号和值,zip 并行遍历多个可迭代对象,默认在最短输入处停止。
  • 浅复制只复制最外层容器;嵌套可变对象仍可能共享。

常见误区

  • 把 list.sort() 的返回值赋回列表
  • 遍历 dict 时同时改变其大小
  • 用可变 list 当字典键
  • 把 set 当成有固定顺序的序列

适用边界

  • 大量从队首删除时 list.pop(0) 是 O(n),应使用 collections.deque。
  • 需要有序映射的特殊操作、计数或默认值时可查阅 collections,但先理解基本 dict。
打开本章完整示例与独立阅读页 →
计算机基础进制、整数表示与位运算从位权理解二、八、十六进制,准确使用补码模型、移位、掩码和 Python 大整数。

正式定义

b 进制数按位权 b⁰、b¹…表示数值。进制只是同一个整数的书写方式;位运算直接处理整数的二进制位。Python 整数精度只受可用内存限制,负数位运算按无限长二进制补码语义定义。

必须掌握

  • bin/oct/hex 生成带前缀字符串,int(text, base) 按指定进制解析;0b、0o、0x 是整数字面量前缀。
  • 手工转十进制用位权展开,十进制转其他进制可连续除基取余并逆序。
  • & 取共同为 1 的位,| 合并置位,^ 标记不同位,~x 等于 -x-1。
  • x << k 相当于 x * 2**k;对非负整数 x >> k 相当于 x // 2**k。
  • 掩码可检测、设置、清除或翻转特定位;位编号通常从最低位 0 开始。
  • 固定字长语言的溢出和 Python 大整数行为不同,题目必须明确字长和有无符号。

常见误区

  • 把进制字符串当成不同数值类型
  • 忘记位编号从 0 开始
  • 照搬固定 32 位溢出结论到 Python
  • 对负数右移套用无符号模型

适用边界

  • 浮点数遵循 IEEE 754 的实现细节,不使用本章的普通整数进制模型直接推导。
  • 字符编码把字符映射到整数,但编码知识与整数进制书写是两个不同层次。
打开本章完整示例与独立阅读页 →
Python 基础条件、循环与程序流程准确理解 if、for、while、range、break、continue 和循环嵌套,而不是背代码模板。

正式定义

控制流决定下一条要执行的语句。分支依据布尔条件选择路径;循环在满足规则时重复执行代码块。Python 用冒号和缩进界定代码块。

必须掌握

  • if/elif/else 从上到下判断,只执行第一个为真的分支;else 不写条件。
  • for 依次取得可迭代对象中的元素;range(start, stop, step) 包含 start、不包含 stop,step 不能为 0。
  • while 在每轮开始前检查条件;循环体必须让状态向终止条件推进。
  • break 结束最内层循环,continue 跳过本轮剩余语句,循环的 else 仅在没有被 break 终止时执行。
  • 嵌套循环的总执行次数通常需要把各层次数相乘;内层 break 不会结束外层循环。
  • 边界测试至少覆盖空范围、单个元素、第一项命中、最后一项命中和始终不命中。

常见误区

  • range 的右端点多算或少算一次
  • while 忘记更新状态造成死循环
  • 把两个互斥条件写成两个独立 if
  • 误以为 break 会跳出所有嵌套循环

适用边界

  • 流程图是算法的表示方法,不是 Python 语法。
  • 递归也能表达重复,但有调用开销和递归深度限制,不能无条件代替循环。
打开本章完整示例与独立阅读页 →

完成检查

确认自己会解释、会编写、会验证