上一篇:06 字典:键值对组织数据(增删改查 · 嵌套 · JSON 数据思维)
上篇练习参考答案
练习 1(两层访问):对下面这个字典,各用一行代码取出"李四的手机"和"赵六的城市",并写出把赵六城市改成"深圳"的一行:
contacts = {
"张三": {"phone": "138****5678", "city": "北京"},
"李四": {"phone": "139****1234", "city": "上海"},
"赵六": {"phone": "137****9012", "city": "杭州"},
}
print(contacts["李四"]["phone"]) # 139****1234
print(contacts["赵六"]["city"]) # 杭州
contacts["赵六"]["city"] = "深圳" # 两层定位,直接赋值
练习 2(预测再验证):len({"a": 1, "b": 2})、{"a": 1}["a"]、{"a": 1}.get("b", 0)、"a" in {"a": 1} 各是什么?写下答案,进交互模式验证,错的贴评论区; 
len({"a": 1, "b": 2}) → 2(数对数); {"a": 1}["a"] → 1; {"a": 1}.get("b", 0) → 0(兜底值); "a" in {"a": 1} → True(in 查的是键)。
练习 3(课程成绩单):建字典 scores = {"Python": 92, "Excel": 85, "汇报": 78},用 .values() 打印:门数、总分、平均分(一位小数)、最高分;再用 3.4 节的两行遍历模板,逐行打印每门课
scores = {"Python": 92, "Excel": 85, "汇报": 78}
print(scores.values()) # 把所有值取出为列表
print(len(scores.values())) # 门数
print(sum(scores.values())) # 总分
print(max(scores.values())) # 最高分
print(f"{sum(scores.values()) / len(scores):.1f}") # 平均分(一位小数)
# 逐行打印每门课
print("\\n=========== 逐行打印每门课 ===========")
for subject, score in scores.items():
print(f"{subject}:{score} ")
3 门、总分 255、平均 85.0、最高 92;
练习 4(疫苗揭晓):执行 print(budget[“技术部”] > 30000)(budget 用本篇数据),看输出是哪个老朋友——下一篇,程序要开始自己拿主意了。
budget["技术部"] > 30000 → True。 03 篇的布尔值老朋友——比较的结果是布尔值,而"根据布尔值走不同路",就是本篇的全部内容。
一、场景引入:让程序第一次"拿主意"
前六篇的程序都是"一条道走到黑":从第一行执行到最后一行,一行不落。但真实的工作流程充满岔路:
- 报销单低于 500 元自动通过,超过 2000 元要总监签字;
- 文件是 Excel 才往里读,是别的就跳过;
- 商品降了价才发提醒邮件,没降就不发。
条件判断(if)就是给程序装上岔路口:它先算出一个布尔值(03 篇学的那种 True/False),True 走这条路,False 走那条路。从此程序不再是复读机,而是会看情况办事的流程引擎——Excel 里的 IF 函数、财务的审批流规则,本质都是它。
本篇结尾你会做出上面那个"差旅报销审批器":三张报销单,各自命中不同的审批路径。同时你会遇到 Python 里第一个纯粹的新语法——缩进。别慌,第 2 篇埋的伏笔(“行首空格有含义”)今天兑现。
二、本篇目标
三、知识点讲解
3.1 if 起步:冒号 + 缩进,代码块的第一次登场
最小可用的条件判断长这样:
amount = 380
if amount < 500:
print("自动通过")
print("已抄送财务")
print("—— 本单处理完毕 ——")

amount < 500 算出 True,于是下面缩进的两行被执行。四个零件各自的作用:
- if:关键字,宣布"如果";
- amount < 500:条件,必须算出一个布尔值(True / False);
- ::冒号,宣布"下面开始一段从属于这个 if 的代码";
- 缩进(行首 4 个空格):标明哪些行"归这个 if 管"。
缩进是本篇唯一的新语法,值得多说两句。 大多数语言用大括号 {} 圈出从属代码,Python 直接用行首空格: 
上面代码里,缩进的两行是 if 的代码块(条件为 True 才执行);最后那行顶格(不缩进),它不听 if 的,永远执行。这就是第 2 篇报错 4"行首多了空格会报错"的原因——不是空格不能有,而是每一级空格都在表达从属关系,乱加就乱了辈分。
三条实操规矩:① 冒号后回车,VS Code 会自动帮你缩进;② 代码块统一缩 4 个空格(Python 社区标准);③ 同一个块内的各行缩进量必须完全一致(Tab 和空格别混用)。
3.2 二选一与多分支:else 和 elif
else——否则(False 时的出路):
if amount < 500:
print("自动通过")
else:
print("转人工审批")

elif——多岔路口(“否则如果”)。报销审批的真实规则是三档,一条链写完:
amount = 1600
if amount < 500:
print("审批路径:自动通过")
elif amount <= 2000:
print("审批路径:主管审批")
else:
print("审批路径:总监审批")

elif 链的运行规则只有一条:从上往下逐个测试,命中一个就执行它的块,其余全部跳过——三个分支永远只走一条。else 是兜底,不写条件、负责"以上都不满足",建议永远写上,防止数据漏网。
两个必须练熟的细节:
- 顺序:从小到大排(先 < 500,再 <= 2000,最后 else)。如果把大条件放前面,它会把后面全部挡住——这正好是第六节坑 2 的内容;
- 边界:< 500 和 <= 2000 意味着——正好 500 元走主管审批(500 不小于 500),正好 2000 元也走主管审批(2000 不大于 2000)。边界值落在哪一档,由 < 还是 <= 一字决定,第六节坑 1 专讲这个。
3.3 比较与逻辑运算符:条件的乐高积木
六个比较运算符(x = 500 ,x 赋值 500 时):
| == | 等于 | x == 500 → True |
| != | 不等于 | x != 500 → False |
| > / >= | 大于 / 大于等于 | x > 500 → False,x >= 500 → True |
| < / <= | 小于 / 小于等于 | x < 500 → False |
03 篇的手指口诀再次上岗:一个等号 = 是"给"(赋值),两个等号 == 是"问"(比较)。在 if 里写 if x = 5: 会直接报错——好在 Python 的报错提示非常贴心。 
三个逻辑运算符——把小条件拼成大条件:
amount = 2600
level = 5
print(amount > 2000 and level >= 5) # True:and——两边都真才真
print(amount > 2000 or level >= 9) # True:or——一边真就是真
print(not amount > 2000) # False:not——真假取反

人话版:and 是"既要又要",or 是"满足其一即可",not 是"偏偏不要"。写审批规则全靠它们:
- “金额超 2000 且 职级 5 以上且 是交通类” → amount > 2000 and level >= 5 and cat == "交通"
- “财务 未 抽查过” → not checked(checked 是 03 篇的布尔变量)
优先级(not > and > or)不用背:条件一复杂就加括号,(a and b) or c 比背规则可靠得多。
3.4 in 做判断:前三篇总复习
in 在 04、05、06 篇都露过脸——现在正式把它编入条件部队,并看清它在三种容器里的查法差异:
print("交通" in ["交通", "住宿", "餐饮"]) # True:列表——整项精确匹配(05 篇)
print("交" in "交通住宿") # True:字符串——子串包含(04 篇)
print("交通" in {"交通": 380}) # True:字典——查的是键(06 篇)

进条件里就是一条真实业务规则——“这三类报销必须附发票”:
need_type = "交通"
need_invoice = ["交通", "住宿", "餐饮"]
if need_type in need_invoice:
print("该类别报销必须附发票")

not in 是它的反面:“附件里不含发票就退回”。到这里,你的条件工具箱集齐了:比较运算符管大小,in 管归属,and/or/not 管组合。
四、完整实战:差旅报销审批器
场景:财务收到三张报销单,规则:低于 500 自动通过;500~2000 主管审批;超过 2000 总监审批;交通类超 1500 要附行程单;高管(职级 5+)大额交通走绿色通道。新建 差旅报销审批器.py:
# ===== 差旅报销审批器 =====
print("=" * 46)
print(" 差旅报销审批器")
print("=" * 46)
# ———- 单据 1:小额交通 ———-
cat1, amount1, level1 = "交通", 380, 3
print(f"\\n单据 1:{cat1}费 {amount1} 元(报销人职级 {level1})")
if amount1 < 500:
print(" 审批路径:自动通过")
elif amount1 <= 2000:
print(" 审批路径:主管审批")
else:
print(" 审批路径:总监审批")
if cat1 == "交通" and amount1 > 1500:
print(" 附加材料:请附行程单")
else:
print(" 附加材料:无")
# ———- 单据 2:中等住宿 ———-
cat2, amount2, level2 = "住宿", 1600, 3
print(f"\\n单据 2:{cat2}费 {amount2} 元(报销人职级 {level2})")
if amount2 < 500:
print(" 审批路径:自动通过")
elif amount2 <= 2000:
print(" 审批路径:主管审批")
else:
print(" 审批路径:总监审批")
if cat2 == "住宿" and amount2 > 1500:
print(" 附加材料:请附入住水单")
else:
print(" 附加材料:无")
# ———- 单据 3:大额机票 + 绿色通道 ———-
cat3, amount3, level3 = "交通", 2600, 5
print(f"\\n单据 3:{cat3}费(机票){amount3} 元(报销人职级 {level3})")
if amount3 < 500:
print(" 审批路径:自动通过")
elif amount3 <= 2000:
print(" 审批路径:主管审批")
else:
print(" 审批路径:总监审批")
# 绿色通道:金额大 + 职级高 + 交通类,三条件缺一不可
if amount3 > 2000 and level3 >= 5 and cat3 == "交通":
print(" 绿色通道:职级 5 以上出行,总监审批后直接放行")
if cat3 == "交通" and amount3 > 1500:
print(" 附加材料:请附行程单")
else:
print(" 附加材料:无")
# ———- 收尾:not 与 in 的组合 ———-
need_invoice = ["交通", "住宿", "餐饮"]
checked = False # 本单是否已被财务抽查(03 篇的布尔变量)
print("-" * 46)
if cat3 in need_invoice:
print(f"提醒:{cat3}类报销必须附发票")
if not checked:
print(f"预警:单据 3 尚未被抽查,已进入财务抽查队列")
print("=" * 46)
两处提前说明:第一行 cat1, amount1, level1 = "交通", 380, 3 是多变量一行赋值(打包拆包,很常用,顺嘴记住);收尾的 not checked 读作"没被抽查过"——布尔变量配 not 是天然搭档,比写 checked == False 地道。
另外,你可能已经手痒了:三张单据的判断逻辑几乎一模一样,居然复制粘贴了三遍。 这个痒处先忍住——单据要是 30 张呢?08 篇循环和 09 篇函数,就是根治它的药。
五、运行效果

==============================================
差旅报销审批器
==============================================
单据 1:交通费 380 元(报销人职级 3)
审批路径:自动通过
附加材料:无
单据 2:住宿费 1600 元(报销人职级 3)
审批路径:主管审批
附加材料:请附入住水单
单据 3:交通费(机票)2600 元(报销人职级 5)
审批路径:总监审批
绿色通道:职级 5 以上出行,总监审批后直接放行
附加材料:请附行程单
———————————————-
提醒:交通类报销必须附发票
预警:单据 3 尚未被抽查,已进入财务抽查队列
==============================================

三张单据走出了三条不同的路,靠的就是同一段 if/elif/else 对不同数据的不同反应——这就是"程序拿主意"。
六、常见报错与排查
报错 1:IndentationError: expected an indented block after 'if' statement(冒号后忘了缩进)
if 5 > 3:
print("自动通过")
IndentationError: expected an indented block after 'if' statement on line 1

原因:冒号宣布"下面有块代码",结果下一行顶格了——宣布了却没有。 解决:给 if 下面的行加 4 空格缩进。这个报错和第 2 篇的 unexpected indent(多了空格)是一对反义词:一个"该缩没缩",一个"不该缩缩了"。
报错 2:SyntaxError: invalid syntax. Maybe you meant '==' …(在 if 里写了一个等号)
if x = 5:
print("通过")
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
原因:03 篇口诀反面教材——= 是赋值,条件里要的是比较 ==。 解决:Python 这次把答案直接递到你嘴边了(Maybe you meant '=='),改成 if x == 5: 即可。
报错 3:SyntaxError: expected ':'(丢了冒号)
if amount < 500
print("自动通过")
SyntaxError: expected ':'

原因:if 行末少了冒号。新手上榜第二名(第一名是中文标点)。 解决:if、elif、else 行末都必须有英文冒号。
坑 1(不报错但走错路):< 和 <= 一字之差,边界值换了赛道
elif amount <= 2000 写成 elif amount < 2000,程序照跑、不报错,但正好 2000 元的单据从"主管审批"掉进了"总监审批"。财务对账时才会发现。 预防:写完边界条件,拿边界值本身(500、2000)当测试数据跑一遍——练习 1 就练这个。
坑 2(不报错但走错路):分支顺序写反,大条件挡住小条件
if amount > 0: # 任何正数都命中这里!
print("主管审批")
elif amount > 2000:
print("总监审批") # 永远轮不到
原因:elif 链"从上往下、命中即停"。amount > 0 挡在前面,后面的分支成了摆设。 预防:范围从小到大排,最具体的条件放最前面。
坑 3(不报错但全走 else):拿字符串和数字比相等
amount = "500" # 从 Excel 读出来的,可能是字符串
print(amount == 500) # False!不报错,但永远不相等
"500" == 500 安静地返回 False——字符串和数字永远不相等,于是所有判断全部落进 else。这是模块二 Excel 实战的第一大坑(04 篇选做题的加强版):读出数据先 type() 体检,该变身就 int() / float()。
七、练习作业(5 分钟)
if amount < 500:
print("自动通过")
elif amount <= 2000:
print("主管审批")
else:
print("总监审批")
下一篇预告:《08 循环:自动化的灵魂》——for、while、range、break/continue、enumerate。批量处理一整列数据,你写的代码从"处理一条"到"处理一沓",从此才算真正的自动化。
网硕互联帮助中心




评论前必须登录!
注册