云计算百科
云计算领域专业知识百科平台

07 条件判断:让程序学会选择(if · elif · else · 逻辑运算符)

上一篇: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 篇埋的伏笔(“行首空格有含义”)今天兑现。

二、本篇目标

  • 正确写出 if / elif / else 三件套,真正理解冒号和缩进(不是死记格式);
  • 会用六个比较运算符和三个逻辑运算符(and / or / not)组合任意条件;
  • 会用 in 做判断(列表、字符串、字典三栖通用,前三篇总复习);
  • 能识别三个"不报错但走错路"的静默坑(本篇报错区的重头戏)。
  • 三、知识点讲解

    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 分钟)

  • 边界纸笔题(本篇核心题):对下面这段代码,写出 amount 为 499 / 500 / 2000 / 2001 时的输出,先笔答再上机:
  • if amount < 500:
    print("自动通过")
    elif amount <= 2000:
    print("主管审批")
    else:
    print("总监审批")

  • 预测再验证:5 > 3 and 2 > 4、5 > 3 or 2 > 4、not 5 > 3、"张" in "张三"、"张三" in ["张三", "李四"]、"李四" in {"李四": 18} 各是什么?写下答案进交互模式验证,错的贴评论区;
  • 请假审批器:写一段 if/elif/else——请假 days <= 1 主管批;days <= 3 经理批;超过 3 天总监批;另外工龄满 5 年(years >= 5)的无论哪档,加一句"可用年假抵扣";
  • 选做(08 篇疫苗):实战代码里判断逻辑抄了三遍,你已经痒了。现在想象单据是一整个列表 claims = [380, 1600, 2600, 990, 4200]——照现在的写法得复制五遍。先别学新东西,试着用现有知识想一个"笨办法"处理它(比如……逐个写?),体会一下痛感——08 篇的 for 循环,三行解决这个列表。

  • 下一篇预告:《08 循环:自动化的灵魂》——for、while、range、break/continue、enumerate。批量处理一整列数据,你写的代码从"处理一条"到"处理一沓",从此才算真正的自动化。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 07 条件判断:让程序学会选择(if · elif · else · 逻辑运算符)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!