前三章的程序按照从上到下的单一路径顺序执行。
现实业务往往充满条件与选择。
业务规则
- 网购订单满 99 元免除运费,否则收取基础运费。
- 账户余额充足时扣款成功,否则提示支付失败。
- 考核成绩达到 60 分为及格,否则为不及格。
本章主线
- 单分支、双分支与多分支。
- 复合条件、短路求值与独立判断。
- 分支嵌套与函数中的整合应用。
扩展:条件表达式与卫语句。
Python 程序设计 · 第四章
if 语句与分支结构Conditional Branching
根据运行时的状态进行判断,
进而决定执行哪条路径上的程序。
章节导入
前三章的程序按照从上到下的单一路径顺序执行。
现实业务往往充满条件与选择。
扩展:条件表达式与卫语句。
4.1 条件成立时才执行
if 语句与代码块if 条件表达式:
条件成立时执行的语句 1
条件成立时执行的语句 2
分支结束后继续执行的后续语句
单分支结构:条件成立时执行,
条件不成立时直接跳过。
if 声明一个条件分支。缩进恢复到与 if 对齐时,表示退出代码块,重回主执行流程。
4.1 案例说明
订单金额达到 99 元时免除运费,
未达到时收取 6 元基础运费。
| 订单金额 | 是否达到免运费门槛 | 最终运费 | 实付金额 |
|---|---|---|---|
| 85.0 元 | 否,跳过分支 | 6.0 元 | 91.0 元 |
| 99.0 元 | 是,执行分支 | 0.0 元 | 99.0 元 |
| 120.0 元 | 是,执行分支 | 0.0 元 | 120.0 元 |
先预设基础运费,条件成立时调整为零。
分支结束后,统一计算实付金额。
4.1 案例代码
PYTHON
order_amount = 120.0 # 订单金额
shipping_fee = 6.0 # 预设基础运费
if order_amount >= 99.0:
shipping_fee = 0.0
total = order_amount + shipping_fee
print(f"运费:{shipping_fee:.2f} 元")
print(f"实付金额:{total:.2f} 元")
4.1 随堂练习 · 题目
将订单金额依次修改为 98.0、99.0 与 100.0。
先手动推算运费与实付总额,再运行代码核对。
| 订单金额 | 条件是否成立 | 最终运费 | 实付金额 |
|---|---|---|---|
| 98.0 元 | ? | ? | ? |
| 99.0 元 | ? | ? | ? |
| 100.0 元 | ? | ? | ? |
注意“达到 99 元”包含恰好 99 元的情形。
4.1 随堂练习 · 核对
分别修改第一行,再运行
order_amount = 98.0 # 再改为 99.0、100.0
shipping_fee = 6.0
if order_amount >= 99.0:
shipping_fee = 0.0
total = order_amount + shipping_fee
print(f"运费:{shipping_fee:.2f} 元")
print(f"实付金额:{total:.2f} 元")
4.2 执行 A 还是执行 B?
if/else:二选一的处理if 条件表达式:
条件成立时执行的语句
else:
条件不成立时执行的语句
分支结束后继续执行的后续语句
双分支结构最核心的特点是互斥。
else 必须与配对的 if 保持相同缩进。else 后直接写冒号,不能附加判断条件。分支执行完毕后,程序汇合至后续语句,继续往下执行。
4.2 案例说明
余额充足时,扣款并提示支付成功。
余额不足时,不能扣款,并提示支付失败。
| 初始余额 | 支付金额 | 执行分支 | 扣款后余额 |
|---|---|---|---|
| 120.0 元 | 114.0 元 | 扣款成功 | 6.0 元 |
| 100.0 元 | 114.0 元 | 扣款失败 | 100.0 元 |
| 114.0 元 | 114.0 元 | 扣款成功 | 0.0 元 |
余额恰好等于支付金额时,也可以完成支付。
支付失败时,账户余额保留原值。
4.2 案例代码
PYTHON
account_balance = 120.0
payment = 114.0
if account_balance >= payment:
account_balance = account_balance - payment
print("支付成功")
else:
print("余额不足,支付未完成")
print(f"当前余额:{account_balance:.2f} 元")
4.3 多分支 · 案例说明
| 成绩区间 | 评定等级 |
|---|---|
| 90 分及以上 | 优秀 |
| 80 分至 89 分 | 良好 |
| 60 分至 79 分 | 及格 |
| 60 分以下 | 不及格 |
一个具体的成绩值,只能归属于其中某一个等级。
Python 使用 if/elif/else 表达这种多选一的决策。
elif 意为“否则,如果……”:只有前面的条件都不成立时,才检查当前条件。
表格按整数成绩表述。代码也能处理小数,例如 89.5 分属于良好。成绩范围按 0–100 分考虑。
4.3 案例代码
PYTHON
score = 85
if score >= 90:
grade = "优秀"
elif score >= 80:
grade = "良好"
elif score >= 60:
grade = "及格"
else:
grade = "不及格"
print(f"成绩:{score} 分,等级:{grade}")
4.3 执行机制
条件范围相互包含时,先判断更严格的条件,
再判断更宽松的条件。
| 比较方式 | 阈值排列 | 原理 |
|---|---|---|
单侧下界 >= | 从大到小:90、80、60 | 数值越大,覆盖范围越小 |
单侧上界 <= | 从小到大 | 数值越小,覆盖范围越小 |
95 分同时满足 90、80、60 分三个下界。若先检查 60 分,
就会提前命中“及格”,无法执行下方更严格的“优秀”分支。
能走到 80 分条件,已经排除了 90 分及以上,因此无需重复写小于 90 分的限制。
4.4 同时判断多个条件
and、or、not| A | B | A and B | A or B |
|---|---|---|---|
| False | False | False | False |
| True | False | False | True |
| False | True | False | True |
| True | True | True | True |
此表以操作数本身为布尔值为前提。
布尔变量可直接作为条件,无需再与 True 比较。
4.4 案例说明
订单金额满 99 元或为 VIP 会员可免运费,
但偏远地区除外。
使用圆括号将需要组合的条件括起来,使业务含义一目了然。
常用优先级从高到低:
算术运算、比较运算、not、and、or。
优先级决定表达式怎样结合。运行时仍遵循求值顺序与短路规则。
4.4 案例代码
PYTHON
order_amount = 85.0
is_vip = True
is_remote_area = False
if (order_amount >= 99.0 or is_vip) and not is_remote_area:
shipping_fee = 0.0
else:
shipping_fee = 6.0
print(f"运费:{shipping_fee:.2f} 元")
4.4 常见误区 · 问题说明
判断优惠码是否为 SAVE10 或 VIP10 时,or 两边必须各自写出完整的比较表达式。
区分表达式返回的对象,与该对象在条件判断中的真假性。
Python 的 and 与 or 返回决定结果的操作数本身,not 始终返回布尔值。
4.4 常见误区 · 代码对照
错误写法
# 错误示范:右边没有进行比较
if coupon_code == "SAVE10" or "VIP10":
...
正确写法
coupon_code = "VIP10"
if coupon_code == "SAVE10" or coupon_code == "VIP10":
print("优惠码验证有效")
else:
print("优惠码无效")
4.4 短路求值 · 案例说明
从左到右计算时,一旦左边已经确定整体真假,
解释器就停止计算后续表达式。
| 表达式 | 左边结果 | 是否计算右边? |
|---|---|---|
A and B | False | 否,短路跳过 |
A or B | True | 否,短路跳过 |
科目数为 0 时,直接除以科目数会报错。
先把检查条件放在左边,把依赖该条件的计算放在右边。
4.4 短路求值 · 案例代码
and 跳过除以零的计算PYTHON
total_score = 150.0
course_count = 0
if course_count > 0 and (total_score / course_count) >= 60.0:
print("考核达标")
else:
print("无有效成绩或考核未达标")
4.5 案例说明
if 与一组分支链同样是消费 250 元,
赠品能否同时获得,取决于业务规则。
| 规则特点 | 店铺规则 | 采用结构 |
|---|---|---|
| 可以叠加 | 满 100 元送优惠券, 满 200 元额外送帆布袋 | 多个独立的 if |
| 互斥,只能选其一 | 满 200 元只送帆布袋, 满 100 元但不足 200 元只送优惠券 | 一组 if/elif |
独立判断可以同时触发多个结果。
一组分支链命中后结束,最多只执行一个分支。
4.5 案例代码
order_amount = 250.0
if order_amount >= 100.0:
print("赠送一张优惠券")
if order_amount >= 200.0:
print("赠送一个定制帆布袋")
赠送一张优惠券 赠送一个定制帆布袋
order_amount = 250.0
if order_amount >= 200.0:
print("赠送一个定制帆布袋")
elif order_amount >= 100.0:
print("赠送一张优惠券")
赠送一个定制帆布袋
4.6 嵌套分支 · 案例说明
先检查用户是否登录。
已经登录时,再判断是不是 VIP 会员。
| 登录状态 | 会员身份 | 处理方式 |
|---|---|---|
| 未登录 | 无需判断 | 提示“请先登录” |
| 已登录 | 普通用户 | 展示 100 元原价 |
| 已登录 | VIP 会员 | 展示 80 元特权价 |
在一个分支的内部代码块里,再写一个完整的 if 语句,
就叫做嵌套分支。
4.6 案例代码
else 与哪个 if 配对PYTHON
is_logged_in = True
is_vip = False
if is_logged_in:
if is_vip:
price = 80.0
else:
price = 100.0
print(f"商品价格:{price:.2f} 元")
else:
print("请先登录后查看价格")
4.7 函数中的分支 · 案例说明
计费重量为正整数,
单位为公斤。
| 计费情况 | 运费 |
|---|---|
| 不超过 1 公斤 | 12 元 |
| 超过 1 公斤 | 12 + (重量 − 1) × 5 元 |
return。这种写法称为单出口结构。
4.7 案例代码
PYTHON
def calculate_freight(weight: int) -> int:
"""根据快递重量计算运费。"""
if weight <= 1:
freight = 12
else:
freight = 12 + (weight - 1) * 5
return freight
print(calculate_freight(1))
print(calculate_freight(2))
print(calculate_freight(4))
核心练习 1 · 题目
标准配送费为 5.0 元。餐品总额达到 30.0 元
及以上,或下单用户为 VIP 时,免收配送费。
实付金额为餐品总额与配送费之和。请设计函数名称、参数、
类型标注与返回值,并根据以下用例自测。
| 餐品金额 | 是否为 VIP | 期望返回值 |
|---|---|---|
| 25.0 | False | 30.0 |
| 30.0 | False | 30.0 |
| 25.0 | True | 25.0 |
核心练习 1 · 参考代码
PYTHON
def calculate_takeout_total(
food_total: float, is_vip: bool
) -> float:
"""根据餐品金额与会员身份计算外卖订单实付总额。"""
if food_total >= 30.0 or is_vip:
delivery_fee = 0.0
else:
delivery_fee = 5.0
return food_total + delivery_fee
print(calculate_takeout_total(25.0, False))
print(calculate_takeout_total(30.0, False))
print(calculate_takeout_total(25.0, True))
核心练习 2 · 题目
打印页数越多,单页单价越优惠。
总费用等于打印页数乘以对应的单页单价。
| 打印页数(正整数) | 单页单价 | 边界自测 |
|---|---|---|
| 不满 20 页 | 0.5 元 / 页 | 19 页:9.5 元 |
| 20 页至 49 页 | 0.4 元 / 页 | 20 页:8.0 元;49 页:19.6 元 |
| 50 页及以上 | 0.3 元 / 页 | 50 页:15.0 元 |
请自主设计函数接口,并考虑多分支条件的排列顺序。
核心练习 2 · 参考代码
PYTHON
def calculate_printing_fee(pages: int) -> float:
"""根据打印总页数按阶梯标准计算应收费用。"""
if pages >= 50:
unit_price = 0.3
elif pages >= 20:
unit_price = 0.4
else:
unit_price = 0.5
return pages * unit_price
print(calculate_printing_fee(19))
print(calculate_printing_fee(20))
print(calculate_printing_fee(49))
print(calculate_printing_fee(50))
核心练习 3 · 题目
先检查订单是否已取消。
订单未取消时,继续检查账户余额是否足够支付。
| 订单已取消 | 账户余额 | 应付金额 | 期望返回值 |
|---|---|---|---|
| True | 120.0 | 114.0 | 订单已取消 |
| False | 120.0 | 114.0 | 可以支付 |
| False | 100.0 | 114.0 | 余额不足 |
| False | 114.0 | 114.0 | 可以支付 |
使用两层嵌套分支,在外层 else 内检查余额。
使用变量记录提示文本,在函数末尾统一返回字符串。
核心练习 3 · 参考代码
PYTHON
def get_payment_message(
is_cancelled: bool, account_balance: float, payment: float
) -> str:
"""分层检查订单状态与账户余额,返回支付提示文本。"""
if is_cancelled:
message = "订单已取消"
else:
if account_balance >= payment:
message = "可以支付"
else:
message = "余额不足"
return message
第二部分 · 扩展知识点 4.8
只是根据某个条件,在两个备选值中选出一个时,
可以使用更紧凑的条件表达式。
目标变量 = 值1 if 条件 else 值2首先判断中间的条件。
成立取左侧值,不成立取右侧值。
金额达到 99 元,运费为 0 元;
否则,运费为 6 元。
适合简单赋值。分支内需要多步处理,或逻辑复杂时,使用标准的多行分支结构更清晰。
4.8 扩展案例 · 代码
PYTHON
order_amount = 120.0
shipping_fee = 0.0 if order_amount >= 99.0 else 6.0
print(f"运费:{shipping_fee:.2f} 元")
先判断条件,再选择其中一个值。
扩展知识点 4.9 · 案例说明
return 提前退出函数函数一旦执行到 return,便立即结束运行,
将结果返回给调用方,其后的代码不再执行。
| 回顾支付状态检查 | 提前返回的处理 |
|---|---|
| 订单已取消 | 立即返回“订单已取消” |
| 订单未取消,余额足够 | 返回“可以支付” |
| 其余情况 | 末尾默认返回“余额不足” |
这种写法称为卫语句,也称为提前返回。
提前排除特殊情况,可以减少嵌套缩进。
4.9 扩展案例 · 代码
PYTHON
def get_payment_message(
is_cancelled: bool, account_balance: float, payment: float
) -> str:
if is_cancelled:
return "订单已取消"
if account_balance >= payment:
return "可以支付"
return "余额不足"
print(get_payment_message(True, 120.0, 114.0))
print(get_payment_message(False, 120.0, 114.0))
print(get_payment_message(False, 100.0, 114.0))
本章回顾
| 业务需求 | 控制结构 | 执行特点 |
|---|---|---|
| 条件成立时才执行 | if | 成立执行,否则跳过 |
| 两条互斥路径 | if/else | 有且仅走一条 |
| 多种互斥情况 | if/elif/else | 逐个判断,首个命中后结束 |
| 规则独立,可同时触发 | 多个独立 if | 每个条件分别判断 |
| 后一个判断依赖前提 | 嵌套分支 | 先检查前提,再做细化判断 |
缩进表达从属关系,条件顺序影响执行路径。
复合条件明确分组,边界值用于核对规则。