课程库 › AI 主线 › Python 进阶语法 › 第 7 课
单元测验 + 重构挑战:把一段烂代码改优雅
里程碑约 45 分钟
本课导读
U1.1 的关卡到了,分两关:第一关综合测验 10 题,覆盖本单元全部六课;第二关重构挑战——一段能跑但没法看的真实风格烂代码,用这六课的全部功夫把它改优雅。通过标准:测验全对 + 重构后运行结果与原版一致。预计 45 分钟。
赛前热身:本单元的知识地图
| 课 | 一句话回顾 |
|---|---|
| 1. 列表进阶 | 切片含头不含尾;sorted 复印 .sort 原地;推导式 = 质检+加工流水线 |
| 2. 字典与集合进阶 | .get 兜底;嵌套一层剥一个方括号(JSON 的形状);set 去重 + 交并差 |
| 3. 函数进阶 | 默认参数必填在前;调用时关键字点名;return 多值 → 解包 |
| 4. 作用域与模块 | 函数内赋值是局部变量;参数进 return 出;import 三姿势 + 标准库 |
| 5. 错误与异常处理 | traceback 从最后一行往上读;except 写明类型;预防优先于抢救 |
| 6. 代码风格 | 蛇形命名见名知意;注释说为什么;PEP8 五条最小集 |
第一关:综合测验
1. nums = [5, 2, 8, 1, 9],一行取出“从大到小的前 2 名”的写法是?
2. [len(w) for w in ["ai", "data", "ml"] if len(w) > 2] 的结果是?
3. resp = {"user": {"tags": ["vip", "new"]}},取出 "new" 的写法是?
4. 想统计一个列表里有多少个不同的值,最顺手的写法是?
5. def notify(msg, urgent=False): 定义后,哪个调用会报错?
6. def stats(nums): return max(nums), min(nums) —— 正确接住两个结果的写法是?
7. total = 0,函数体里写 total = total + n 想累加全局的 total,实际会发生什么?
8. import pandas as pd 之后,正确的用法是?
9. int(raw) 转换用户输入,要接住“输入了文字”的意外,except 后面写哪种类型?
10. 下面哪个函数头最符合本单元的风格标准?
第二关:重构挑战
下面这段代码出自"三个月前的你"之手:功能完全正常——统计各部门报销总额、找出超预算的部门。但它集齐了本单元批判过的所有毛病。
你的任务:逻辑和输出保持一致,把它改到能见人。改完运行,输出应与原版一字不差。
改造清单(对照六课逐项检查):
- 函数名、变量名全部换成见名知意的蛇形英文(第 6 课)
-
2000这个魔法数字提成常量或带名字的默认参数(第 3、6 课) - 累加部分用
.get(键, 0)简化 if/else 四行(第 2 课) - 找超标部门那段改成列表推导式(第 1 课)
- 给函数补一行 docstring(第 6 课)
- 运算符、逗号周围的空格补齐;
if ...: d.append(k)这种挤一行的拆开(第 6 课)
💡 提示(卡住了再看)
先只做"改名"这一步——名字换好,代码的意图就浮出来了,其余每项都是局部小手术。累加那四行的 .get 写法:totals[dept] = totals.get(dept, 0) + amount。
✅ 参考实现(先自己改完再对照)
BUDGET_LINE = 2000 # 部门报销预警线(元)
def summarize_expenses(records, budget_line=BUDGET_LINE):
"""汇总各部门报销总额,返回 (总额字典, 超预算部门列表)"""
totals = {}
for dept, amount in records:
totals[dept] = totals.get(dept, 0) + amount
over_budget = [dept for dept, total in totals.items() if total > budget_line]
return totals, over_budget
expenses = [("设计", 1200), ("运营", 800), ("设计", 2300), ("行政", 450), ("运营", 1900)]
totals, over_budget = summarize_expenses(expenses)
print(totals)
print(over_budget)
对照要点:for dept, amount in records 直接解包元组(第 3 课);.get(dept, 0) 三行变一行(第 2 课);超标筛选是带条件的推导式,而且用 .items() 同时拿键值(第 1、2 课)。如果你的版本名字不同但同样清晰——完全没问题,命名没有唯一答案,清晰才是标准。
提示
彩蛋练法:把你重构后的代码发给 AI,让它"按 PEP8 和可读性最佳实践点评"——看看 AI 还能挑出什么。这个动作(写 → 重构 → 请人审)就是真实工程师的成长循环,从今天起它属于你了。
通关小结
走到这里,你的 Python 已经从"会写"升级到"写得像话":
- 数据侧:切片/排序/推导式 + 嵌套结构 + 集合——一批数据的取、排、洗、去重都有了顺手兵器
- 函数侧:默认参数、关键字调用、多值返回——能写出别人(和 AI)乐意用的接口
- 工程侧:作用域心智、import 百宝箱、异常气囊、风格品味——代码开始有"工程"的样子
下个单元换个视角看世界:面向对象初步——为什么字典装数据装到一定程度就不够用了?类(class)登场。
划选正文任意文字可高亮、批注或加入复习卡
讨论
载入中…