# 第 1-5 课:条件判断 ## 一、本课目标 完成本课后,你应该能够: 1. 解释条件判断为什么能让程序作出不同选择; 2. 使用 `if` 在条件成立时执行代码; 3. 使用 `if...else` 处理两种互斥情况; 4. 使用 `if...elif...else` 处理多个分支; 5. 正确书写英文冒号和四个空格缩进; 6. 使用比较运算符和逻辑运算符组成条件; 7. 理解条件顺序为什么会影响最终结果; 8. 使用嵌套条件处理有先后依赖的判断; 9. 编写一个能够根据输入给出不同结论的程序。 ## 二、前置知识 开始本课前,你应该已经掌握: - 使用 `input()` 接收用户输入; - 使用 `int()` 和 `float()` 转换数据; - 使用比较运算符得到 `True` 或 `False`; - 使用 `and`、`or`、`not` 组合条件; - 使用 f-string 输出变量。 ## 三、为什么需要条件判断 前面的程序会从上到下执行每一行代码。即使我们计算出了布尔结果,程序也只是把它显示出来: ```python score = 80 is_passed = score >= 60 print(is_passed) ``` 真实程序通常需要根据结果执行不同操作,例如: - 分数达到 60 分时显示“通过”; - 密码正确时允许登录; - 库存不足时拒绝下单; - 学习任务完成后进入下一课; - 接口调用失败时显示错误信息。 条件判断让程序拥有“如果发生某种情况,就执行某段代码”的能力。 ## 四、最简单的 `if` `if` 的中文含义是“如果”。基本结构如下: ```python if 条件: 条件成立时执行的代码 ``` 示例: ```python score = 80 if score >= 60: print("本次考核通过。") ``` 执行过程: 1. Python 计算 `score >= 60`; 2. 结果为 `True`,因此执行缩进的 `print()`; 3. 如果结果为 `False`,缩进代码会被跳过; 4. 程序继续执行条件结构后面的代码。 ## 五、冒号与缩进 Python 使用缩进表示哪些代码属于某个条件分支。 正确写法: ```python if score >= 60: print("通过") print("可以继续下一阶段") print("评估结束") ``` 两条缩进的 `print()` 都属于 `if`。最后一条没有缩进,因此无论条件是否成立都会执行。 ### 5.1 冒号 条件末尾必须使用英文半角冒号 `:`: ```python if score >= 60: ``` 不能使用中文冒号 `:`,也不能漏写冒号。 ### 5.2 四个空格 Python 官方风格通常使用四个空格作为一级缩进。PyCharm 按下 Tab 键时,一般会自动生成合适的缩进。 同一个代码块中的代码必须保持相同缩进: ```text if score >= 60: print("通过") print("缩进不一致") ``` 这会产生 `IndentationError`,中文可以理解为“缩进错误”。 ## 六、使用 `if...else` 处理两种情况 `else` 表示“否则”。当 `if` 条件不成立时,执行 `else` 分支: ```python score = 55 if score >= 60: print("本次考核通过。") else: print("本次考核未通过。") ``` `if` 与 `else` 只会执行其中一个分支,不会同时执行。 执行逻辑可以表示为: ```text 条件是否成立? ├── 是 → 执行 if 分支 └── 否 → 执行 else 分支 ``` ## 七、使用 `if...elif...else` 处理多个分支 `elif` 是 else if 的缩写,表示“否则如果”。 ```python score = 85 if score >= 90: print("优秀") elif score >= 80: print("良好") elif score >= 60: print("合格") else: print("需要继续练习") ``` Python 会从上到下检查条件: 1. 检查 `score >= 90`,结果为 `False`; 2. 检查 `score >= 80`,结果为 `True`; 3. 执行“良好”; 4. 跳过后面的其他分支。 整组结构最多执行一个分支。 ## 八、条件顺序非常重要 错误顺序示例: ```python score = 95 if score >= 60: print("合格") elif score >= 90: print("优秀") ``` 虽然 95 分符合“优秀”,但第一个条件 `score >= 60` 已经成立,后面的分支不会再检查,最终只会输出“合格”。 处理分数区间时,通常从要求最高、范围最窄的条件开始: ```python if score >= 90: print("优秀") elif score >= 60: print("合格") else: print("未通过") ``` ## 九、条件可以直接使用布尔变量 如果变量本身已经是布尔值,可以直接作为条件: ```python practice_finished = True if practice_finished: print("练习已完成。") else: print("请先完成练习。") ``` 不推荐重复比较: ```python if practice_finished == True: ``` 直接写 `if practice_finished:` 更简洁,也符合 Python 常见风格。 判断布尔值为假时,可以使用 `not`: ```python if not practice_finished: print("请先完成练习。") ``` ## 十、组合多个条件 ### 10.1 使用 `and` 只有课程和练习都完成时,才能进入下一课: ```python course_finished = True practice_finished = True if course_finished and practice_finished: print("可以进入下一课。") else: print("当前课程尚未完成。") ``` ### 10.2 使用 `or` 允许使用 PyCharm 或 VS Code: ```python uses_pycharm = True uses_vscode = False if uses_pycharm or uses_vscode: print("已经具备代码编辑器。") else: print("请先安装代码编辑器。") ``` ### 10.3 使用括号提高可读性 ```python if (score >= 60) and practice_finished: print("考核通过。") ``` 简单比较周围的括号可以省略,但条件较长时,括号能帮助读者快速理解组合关系。 ## 十一、连续区间判断 判断一个数字是否处于某个范围,可以使用 `and`: ```python age = 20 if age >= 18 and age <= 60: print("年龄在 18 到 60 之间。") ``` Python 还支持更接近数学写法的链式比较: ```python if 18 <= age <= 60: print("年龄在 18 到 60 之间。") ``` 两种写法表达相同含义。链式比较是 Python 中常见且清晰的写法。 ## 十二、嵌套条件判断 一个条件分支内部还可以包含另一个条件判断,这称为嵌套(Nesting)。 ```python account_enabled = True password_correct = True if account_enabled: if password_correct: print("登录成功。") else: print("密码错误。") else: print("账户已停用。") ``` 这里必须先确认账户可用,才有必要继续检查密码。 嵌套层级过多会让代码难以阅读。只有当第二个判断确实依赖第一个判断时才使用嵌套;能够清晰地用 `and`、`elif` 表达时,不必强行嵌套。 ## 十三、输入与条件判断 一个完整的交互判断程序: ```python score_text = input("请输入考核分数:") score = float(score_text) if score >= 60: print("考核通过。") else: print("考核未通过。") ``` 输入数据参与数字比较前,仍然需要先完成类型转换。 ## 十四、输入范围校验 分数通常应处于 0 到 100 之间。可以先检查输入范围: ```python if score < 0 or score > 100: print("分数必须在 0 到 100 之间。") elif score >= 60: print("考核通过。") else: print("考核未通过。") ``` 无效数据的判断应放在前面。否则 `score = 120` 可能被错误地归为“通过”。 当前程序仍要求用户输入能够转换为数字的内容。如何处理“abc”等完全不能转换的数据,会在异常处理课程中学习。 ## 十五、哪些值会被当作假 条件不一定必须写比较表达式。Python 会把某些空值当作 `False`: - `False`; - 数字 `0` 和 `0.0`; - 空字符串 `""`。 例如: ```python user_name = input("请输入姓名:") if user_name: print(f"你好,{user_name}!") else: print("姓名不能为空。") ``` 如果用户直接按回车,`user_name` 是空字符串,程序会执行 `else`。 这种根据值判断真假的规则称为真值(Truth Value)。列表、字典等容器的真值将在学到对应数据类型后继续介绍。 ## 十六、运行本课示例 在 PowerShell 中执行: ```powershell cd D:\Code\Python\01_python基础\1_5_条件判断 python conditions.py ``` 示例会要求输入: 1. 考核分数; 2. 是否完成练习,用 `yes` 或 `no` 表示。 建议至少运行以下几组数据: | 分数 | 是否完成练习 | 重点观察 | | --- | --- | --- | | `95` | `yes` | 优秀且允许进入下一课 | | `75` | `no` | 合格但不能进入下一课 | | `50` | `yes` | 未通过 | | `120` | `yes` | 输入范围无效 | ## 十七、常见错误 ### 17.1 漏写冒号 ```text if score >= 60 print("通过") ``` 条件末尾必须有英文冒号 `:`。 ### 17.2 缩进不正确 属于分支的代码必须统一缩进四个空格。不要混用不一致的空格数量。 ### 17.3 使用 `=` 进行比较 ```text if score = 60: ``` 比较是否相等应使用 `==`。 ### 17.4 条件顺序错误 多个分数等级应从高到低判断,否则宽泛条件会提前拦截更精确的分支。 ### 17.5 把多个独立 `if` 当成互斥分支 ```python if score >= 60: print("合格") if score >= 90: print("优秀") ``` 95 分会同时输出“合格”和“优秀”。如果等级只能选择一个,应使用 `if...elif...else`。 ### 17.6 忘记转换输入类型 `input()` 返回字符串。数字范围判断前应使用 `int()` 或 `float()` 转换。 ## 十八、课堂练习 打开 `practice.py`,完成“Agent 学习状态评估器”。程序需要根据学习时长、练习完成情况和测验成绩,输出不同等级与下一步建议。 运行命令: ```powershell python practice.py ``` 完成后至少使用以下测试数据检查不同分支: | 每天学习小时 | 已完成练习 | 测验成绩 | 预期核心结果 | | --- | --- | --- | --- | | `2.5` | `yes` | `95` | 优秀,可以继续 | | `1.5` | `yes` | `75` | 合格,可以继续 | | `0.5` | `yes` | `75` | 时长不足,暂不能继续 | | `2` | `no` | `80` | 练习未完成,暂不能继续 | | `2` | `yes` | `50` | 成绩未通过 | | `2` | `yes` | `120` | 输入无效 | ## 十九、思考题 1. `if` 条件为 `False` 时,缩进代码会怎样? 2. `if...elif...else` 最多会执行几个分支? 3. 为什么分数等级通常从高分向低分判断? 4. 多个独立 `if` 与一组 `if...elif...else` 有什么区别? 5. 为什么输入范围校验应该放在成绩等级判断之前? 6. `if practice_finished:` 为什么不必写成 `if practice_finished == True:`? 7. 空字符串在条件中会被当作真还是假? ## 二十、本课小结 - `if` 在条件为真时执行对应代码; - `else` 处理前面条件都不成立的情况; - `elif` 用于增加互斥分支; - 分支末尾需要英文冒号,分支内部需要统一缩进; - 一组 `if...elif...else` 最多执行一个分支; - 条件顺序会影响最终结果; - 布尔变量可以直接作为条件; - `and`、`or`、`not` 可以组成更完整的判断; - 嵌套条件适合表达有先后依赖的判断; - 空字符串、数字零等值在条件中会被当作假。 ## 二十一、验收标准 - [ ] 能正确书写 `if`; - [ ] 能正确书写 `if...else`; - [ ] 能正确书写 `if...elif...else`; - [ ] 能使用四个空格表示分支代码; - [ ] 能解释条件顺序的重要性; - [ ] 能组合比较运算符与逻辑运算符; - [ ] 能完成简单的输入范围校验; - [ ] 能完成并运行 `practice.py`; - [ ] 能使用多组测试数据覆盖所有主要分支; - [ ] 能回答七道思考题。