第2章 2.1 控制流:if/switch/三元

「上一章我们学会了用模板字符串和运算符来组装数据,这一章我们要问自己一个更关键的问题:程序该走哪条路?」

想象你早上出门前看天气预报:如果下雨就带伞,否则就不带——这就是条件判断。程序也一样,它需要根据不同情况走不同的路。学会了控制流,你的代码才真正开始「动」起来。

学完这章,你能写出:根据成绩自动评级、根据温度推荐穿衣、根据用户输入显示不同结果的智能脚本。


🎯 开场 3 分钟:为什么要学这个?

你有没有遇到过这种场景?

  • 考试成绩出来了,要判断及格还是不及格
  • 网上买东西,要根据会员等级计算不同折扣
  • 天气 App 要根据温度决定显示「穿短袖」还是「套羽绒服」

如果这些事要让程序自动处理,你就需要控制流——让程序学会「见机行事」。

说白了: 控制流就是程序的「方向盘」,让它知道什么时候该拐弯、什么时候该直走。


🧱 基础 25 分钟:核心概念

if 语句:最基本的选择

是什么? if \n\nSimple tech illustration expla\n\nAI comic creation scene, creat\n\n就是「如果……就……」的逻辑。

生活类比: 如果水开了(条件成立),就关火(执行动作)。水没开,就不管它。

怎么用?

# 小明的考试成绩
score = 85

if score >= 60:
print("小明及格了!")

输出:

小明及格了!

这行代码在干嘛:if score >= 60: 检查分数是否大于等于 60,如果是,就执行缩进的代码。


if...else:非此即彼

是什么? else 就是「否则……」。

生活类比: 如果下雨就带伞,否则不带。这两件事互斥,只会执行一个。

怎么用?

score = 45

if score >= 60:
print("及格了,真棒!")
else:
print("不及格,要加油哦!")

输出:

不及格,要加油哦!

这行代码在干嘛:else 处理所有不满足 if 条件的情况。


if...elif...else:多选一

是什么? elif 是「否则如果……」的缩写,可以连着写多个。

生活类比: 考试成绩分类:90分以上是A,80-89是B,70-79是C,60-69是D,60以下是不及格。每个等级只对应一种结果。

怎么用?

score = 78

if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "不及格"

print(f"小明的成绩等级是:{grade}")

输出:

小明的成绩等级是:C

这行代码在干嘛:程序从上往下逐个检查条件,一旦找到满足的,就执行对应的代码块,后面的判断全部跳过。


match...case:Python 版的「switch」

是什么? Python 3.10 引入了 match...case,类似于其他语言的 switch,但更强大。

生活类比: 就像餐厅菜单点菜:顾客说「宫保鸡丁」,服务员就上宫保鸡丁;说「红烧肉」,就上红烧肉。说了一个菜名,就按这个菜名上菜。

怎么用?

# 星期几的工作安排
day = "周三"

match day:
case "周一":
    print("开周会,整理上周总结")
case "周三":
    print("部门培训,学习新技术")
case "周五":
    print("周报提交,项目复盘")
case _:
    print("正常工作日")

输出:

部门培训,学习新技术

这行代码在干嘛:case _ 是「默认」选项,类似于 else,匹配所有没被前面 case 处理的情况。

进阶用法:多个值匹配同一个case

status = "离线"

match status:
case "在线" | "活跃":
    print("用户可以接收消息")
case "离线" | "离开":
    print("消息将延迟送达")
case _:
    print("状态未知")

输出:

消息将延迟送达

三元运算符:一行搞定 if...else

是什么? 三元运算符用一行写完简单的 if...else。

生活类比: 「如果有苹果就买苹果,否则买香蕉」可以简化为「买(有苹果?苹果:香蕉)」。

怎么用?

age = 20
# 条件成立时取前面的值,不成立时取后面的值
result = "成年" if age >= 18 else "未成年"

print(f"小明的年龄是 {age},属于:{result}")

输出:

小明的年龄是 20,属于:成年

这行代码在干嘛:age >= 18 为真,所以 result 赋值为 "成年"。

什么时候用它? 适合简短判断,写成长长的 if...else 太啰嗦时。


None 合并:给「空」一个默认值

是什么? Python 里没有 ?? 运算符,但可以用 or 来实现类似效果。

生活类比: 如果你没带水杯,就用我备用的。这就是「空时用默认值」的逻辑。

怎么用?

# 用户没设置昵称,就显示"匿名用户"
username = None

display_name = username or "匿名用户"
print(f"欢迎,{display_name}!")

输出:

欢迎,匿名用户!

这行代码在干嘛:usernameNone(空),所以 or 后面的 "匿名用户" 被使用了。

注意: 这种写法有个坑——如果 username 是空字符串 "",也会被当成「假」,这是新手常踩的。

# 更严谨的做法
username = ""
display_name = username if username else "匿名用户"
# 或者用这个(Python 3.14+ 可能有 ?? 运算符)

嵌套 if:判断里套判断

是什么? 在 if 里面再写 if,就像「如果是会员,再判断会员等级」。

生活类比: 电影院打折:如果是学生,再看是不是小学生(更便宜)。不是学生就不打折。

怎么用?

is_student = True
age = 12

if is_student:
if age < 14:
    print("小学生半价优惠!")
else:
    print("学生票8折")
else:
print("全价票")

输出:

小学生半价优惠!

坑来了: 嵌套太深代码会很难读,建议用 elif 扁平化处理。


🔥 实战 35 分钟:3 个递进的小项目

项目 1:成绩自动评级器(5 分钟)

场景: 输入一个分数,自动判断等级。

def grade_score(score):
"""根据分数返回等级"""
if score >= 90:
    return "A(优秀)"
elif score >= 80:
    return "B(良好)"
elif score >= 70:
    return "C(中等)"
elif score >= 60:
    return "D(及格)"
else:
    return "F(不及格)"

# 测试一下
test_scores = [95, 82, 71, 65, 45]

for score in test_scores:
result = grade_score(score)
print(f"分数 {score} -> 等级 {result}")

输出:

分数 95 -> 等级 A(优秀)
分数 82 -> 等级 B(良好)
分数 71 -> 等级 C(中等)
分数 65 -> 等级 D(及格)
分数 45 -> 等级 F(不及格)

一句话解释:elif 把所有情况都列出来,程序会自动找到匹配的那个分支。


项目 2:商品折扣计算器(15 分钟)

场景: 根据用户会员等级和消费金额,计算实际付款。

def calculate_discount(member_level, purchase_amount):
"""
计算折扣后的价格
会员等级:gold / silver / normal
"""
final_price = purchase_amount

if member_level == "gold":
    # 金卡会员:满100打7折,不满100打8折
    if purchase_amount >= 100:
        final_price = purchase_amount * 0.7
    else:
        final_price = purchase_amount * 0.8
elif member_level == "silver":
    # 银卡会员:满100打8折,不满100打9折
    if purchase_amount >= 100:
        final_price = purchase_amount * 0.8
    else:
        final_price = purchase_amount * 0.9
else:
    # 普通会员:满200打9折
    if purchase_amount >= 200:
        final_price = purchase_amount * 0.9

return final_price

# 测试数据
customers = [
("gold", 150),
("gold", 80),
("silver", 200),
("silver", 50),
("normal", 250),
("normal", 100),
]

print("=" * 40)
print(f"{'会员等级':^10} {'消费金额':^10} {'应付':^10}")
print("=" * 40)

for member_level, amount in customers:
pay = calculate_discount(member_level, amount)
print(f"{member_level:^10} {amount:^10} {pay:^10.2f}")
print("=" * 40)

输出:

========================================
会员等级    消费金额      应付
========================================
old       150       105.00
old        80        64.00
silver      200       160.00
silver       50        45.00
normal      250       225.00
normal      100       100.00
========================================

一句话解释: 先判断会员等级,再在每个等级里判断消费金额是否达标,层层嵌套但逻辑清晰。


项目 3:天气穿衣推荐小工具(15 分钟)

场景: 根据温度和天气状况,推荐穿什么。

def recommend_outfit(temperature, weather):
"""
根据温度和天气推荐穿着
temperature: 温度(摄氏度)
weather: sunny/rainy/cloudy/windy
"""
# 第一步:根据温度确定基本穿着
if temperature >= 30:
    base = "短袖短裤"
elif temperature >= 20:
    base = "长袖薄裤"
elif temperature >= 10:
    base = "毛衣加外套"
else:
    base = "羽绒服全套"

# 第二步:根据天气加装备
accessories = []

match weather:
    case "rainy":
        accessories = ["雨伞", "防水鞋"]
    case "windy":
        accessories = ["防风帽", "围巾"]
    case "sunny":
        accessories = ["太阳镜", "防晒霜"]
    case "cloudy":
        accessories = ["薄外套备用"]
    case _:
        accessories = []

# 组合建议
outfit = base
if accessories:
    outfit += ",另备:" + "、".join(accessories)

return outfit

# 模拟一周天气
weekly_weather = [
(32, "sunny"),
(15, "rainy"),
(25, "cloudy"),
(8, "windy"),
(35, "sunny"),
(18, "rainy"),
(22, "windy"),
]

print("===== 本周穿衣指南 =====\n")
for temp, weather in weekly_weather:
suggestion = recommend_outfit(temp, weather)
weather_emoji = {"sunny": "☀️", "rainy": "🌧️", "cloudy": "☁️", "windy": "💨"}.get(weather, "❓")
print(f"{weather_emoji} 温度 {temp}°C | {suggestion}")

输出:

===== 本周穿衣指南 =====

☀️ 温度 32°C | 短袖短裤,另备:太阳镜、防晒霜
🌧️ 温度 15°C | 毛衣加外套,另备:雨伞、防水鞋
☁️ 温度 25°C | 长袖薄裤,另备:薄外套备用
💨 温度 8°C | 羽绒服全套,另备:防风帽、围巾
☀️ 温度 35°C | 短袖短裤,另备:太阳镜、防晒霜
🌧️ 温度 18°C | 毛衣加外套,另备:雨伞、防水鞋
💨 温度 22°C | 长袖薄裤,另备:防风帽、围巾

一句话解释: 先用 if 判断温度层,再用 match 判断天气状况,组合出最终建议。


💪 进阶 20 分钟:常见坑 + 性能小贴士

坑 1:缩进错误

# ❌ 错误示例
score = 85
if score >= 60:
print("及格了")  # 没缩进,会报错

# ✅ 正确示例
score = 85
if score >= 60:
print("及格了")  # 必须缩进

说白了: Python 用缩进代替大括号,缩进乱了程序就乱了。


坑 2:条件判断用 = 而不是 ==

# ❌ 错误示例
score = 85
if score = 60:  # 这是赋值,不是比较!
print("及格")

# ✅ 正确示例
score = 85
if score == 60:  # 两个等号才是比较
print("及格")

记忆技巧: 一个等号「把右边的东西放进左边」,两个等号「问左右是不是一样」。


坑 3:三元运算符嵌套

# ❌ 过度嵌套,难读
score = 75
result = "A" if score >= 90 else ("B" if score >= 80 else ("C" if score >= 70 else "D"))

# ✅ 用 elif 更清晰
if score >= 90:
result = "A"
elif score >= 80:
result = "B"
elif score >= 70:
result = "C"
else:
result = "D"

说白了: 三元运算符只适合超简单的判断,复杂情况老老实实用 if...elif


坑 4:or 判断 None 的陷阱

# ❌ 错误示例
username = ""  # 空字符串
display_name = username or "匿名用户"
print(display_name)  # 输出 "匿名用户",但用户明明设置了空字符串

# ✅ 正确示例:显式检查 None
username = ""
display_name = username if username is not None else "匿名用户"

坑来了: or 会把 ""0[] 这些「空值」都当成假,要小心。


坑 5:match...case 的默认分支位置

# ❌ 错误示例
match status:
case _:
    print("未知状态")
case "online":  # 这行永远不会执行
    print("在线")

# ✅ 正确示例:默认分支放最后
match status:
case "online":
    print("在线")
case _:
    print("未知状态")

说白了: case _ 要放在所有具体 case 后面,程序是按顺序匹配的。


性能小贴士:条件顺序影响效率

# 优化前:每次都计算复杂函数
if complex_function() > 0:  # 每次都调用
...

# 优化后:先检查简单条件
result = complex_function()
if result > 0:  # 只调用一次
...

适用场景: 当判断条件涉及函数调用或复杂计算时,把结果存起来再判断,避免重复计算。


调试技巧:用 print 快速定位问题

def find_bug(a, b):
print(f"输入: a={a}, b={b}")  # 打印输入值
result = a + b
print(f"计算中: {a} + {b} = {result}")  # 打印中间结果
return result

find_bug(5, 3)

输出:

输入: a=5, b=3
计算中: 5 + 3 = 8

技巧: 怀疑哪里有问题,就在那一行前面加 print,看实际运行时的值是不是你预期的。


✏️ 练习题 + 作业题

练习题(10 分钟)

练习 1(2 分钟):成绩及格判断
- 输入:score = 58
- 预期输出:不及格,要加油哦!
- 提示:用 else 分支处理不及格情况

练习 2(2 分钟):三元运算简化
- 输入:用三元运算符改写 if age >= 18: print("成年") else: print("未成年")
- 预期输出:一行代码打印结果
- 提示:result = "成年" if age >= 18 else "未成年"

练习 3(2 分钟:加入一个新判断
- 输入:在项目 1 成绩评级器里,加入「满分」的特殊处理(score == 100 返回"满分")
- 预期输出:grade_score(100) 返回 "满分"
- 提示:把 score == 100 放在最前面检查

练习 4(2 分钟):用 match...case 改写
- 输入:把项目 2 的折扣计算用 match...case 改写会员等级判断
- 预期输出:逻辑完全相同,只是写法不同
- 提示:case "gold": 对应金卡会员处理

练习 5(2 分钟):修复报错
- 输入:以下代码报错,找出并修复

score = 85
if score = 60:
print("及格")
  • 预期输出:及格
  • 提示:检查条件判断用的是 = 还是 ==

作业题(30 分钟-2 小时)

做一个「 BMI 身体质量指数计算器」

  • 需求描述: 输入身高(m)和体重(kg),计算 BMI 并给出健康建议
  • 功能点:
    1. 计算 BMI = 体重 / (身高 ^ 2)
    2. 用 if...elif...else 判断:BMI < 18.5 是「偏瘦」,18.5-24 是「正常」,24-28 是「偏胖」,>28 是「肥胖」
    3. 用 match...case 根据体型给出具体建议(如偏瘦建议多吃,肥胖建议运动等)
    4. 支持多次输入计算(输入 q 退出)
  • 加分项:
    1. 用三元运算符在终端显示不同颜色的提示(可以用 ANSI 转义码 \033[92m 绿色 \033[91m 红色)
    2. 保存历史记录到列表,最后打印本次session的所有计算结果
  • 验收标准: 能跑起来 + 输入数据后输出正确 BMI 和建议 + 代码有中文注释
  • 提交方式: 评论区贴代码或 GitHub 链接

📚 总结 + 资源

本文学了 3 件事:
1. 用 if...elif...else 处理多条件分支判断
2. 用 match...case 做清晰的多值匹配(Python 3.10+)
3. 用三元运算符一行搞定简单判断

延伸学习资源:

  1. Python 官方文档:match 语句 —— 官方权威解读
  2. 《Python 编程:从入门到实践》第三章 —— 控制流的实战练习
  3. Real Python: Conditional Statements —— 进阶技巧

互动钩子: 你在写代码时最常遇到的控制流「坑」是什么?是用错了等号、还是缩进乱了?评论区聊聊,老粉优先回复!


下章预告: 学完了「该走哪条路」,下一章我们要解决「这条路要走多少遍」的问题——循环。想象一下,如果有 1000 个成绩要判断等级,用循环 3 行搞定,手动要写 1000 次,你选哪个?

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。