Python(复杂判断)

目录

开篇:为什么需要更复杂的判断?

[1.if-else 双向判断](#1.if-else 双向判断)

语法与语义

2.elif多向判断----让程序拥有多个分支

语法结构

[为什么要用 elif 而不是多个独立的 if?](#为什么要用 elif 而不是多个独立的 if?)

成绩等级示例

季节判断示例(多值匹配)

3.嵌套判断的替代方案

[推荐:使用 elif 和 and 减少嵌套](#推荐:使用 elif 和 and 减少嵌套)

[4. match-case 语句(Python 3.10+)----现代化的模式匹配](#4. match-case 语句(Python 3.10+)----现代化的模式匹配)

[为什么需要 match-case?](#为什么需要 match-case?)

基本要点

解构元组/列表

守卫(guard)

[使用 as 绑定整个匹配对象](#使用 as 绑定整个匹配对象)

5.循环中的else子句

语法

判断列表是否包含奇数

经典用法:素数检测

[注意:不要与 if-else 混淆](#注意:不要与 if-else 混淆)

[6.与循环配合的判断控制:break 和 continue](#6.与循环配合的判断控制:break 和 continue)

[打印 1 到 10 之间的奇数](#打印 1 到 10 之间的奇数)

[输入数字,输入 0 退出](#输入数字,输入 0 退出)

7.复杂判断的性能优化技巧

[1. 将最可能发生的分支放在前面](#1. 将最可能发生的分支放在前面)

[2. 使用字典映射取代长链 if-elif](#2. 使用字典映射取代长链 if-elif)

[3. 使用 match-case(Python 3.10+)](#3. 使用 match-case(Python 3.10+))

[4. 避免在循环内做复杂的判断](#4. 避免在循环内做复杂的判断)

8.常见陷阱与最佳实践

[陷阱 1:elif 条件顺序错误](#陷阱 1:elif 条件顺序错误)

[陷阱 2:忘记写 case _ 导致无匹配时什么都不做](#陷阱 2:忘记写 case _ 导致无匹配时什么都不做)

[陷阱 3:在 match-case 中重复使用变量名导致覆盖](#陷阱 3:在 match-case 中重复使用变量名导致覆盖)

[陷阱 4:混淆 for-else 中 else 的触发条件](#陷阱 4:混淆 for-else 中 else 的触发条件)

[最佳实践:优先使用 match-case 而不是冗长的 if-elif](#最佳实践:优先使用 match-case 而不是冗长的 if-elif)

最佳实践:控制分支深度


开篇:为什么需要更复杂的判断?

上一篇文章我们只学了 if ------ 它只能决定"做"或"不做"。但现实往往不是黑白二元的:比如根据成绩划分 A、B、C、D、F 五个等级;根据用户输入的命令执行不同操作。这就引出了 if-else(二选一)和 elif(多选一)以及更强大的 match-case(模式匹配)。

1.if-else 双向判断

if-else 双向判断 ------ "如果...否则..."

语法与语义

if 条件:

条件为真时执行的代码块

else:

条件为假时执行的代码块

  • if 后面依然是条件,冒号,缩进块。

  • else 后面跟冒号,但没有条件(因为它是所有剩余情况的兜底)。

  • else 的代码块也需缩进。

生活类比

你在路口过马路:如果 绿灯亮就过马路,否则 就等待。这就是一个标准的 if-else

复制代码
score = 55
if score >= 60:
    print("及格")
else:
    print("不及格")

输出"不及格",因为条件为假。else 部分执行。

注意:else不能单独使用,必须与if配对

复制代码
else:        # SyntaxError
    print("no if")

if-else可以嵌套,但是不推荐深度嵌套

嵌套深度超过 2 层时,代码可读性会急剧下降。尽量用 and 或重构函数来减少嵌套。


2.elif多向判断----让程序拥有多个分支

当你有三个或更多互斥的可能性时,if-else 就不够了。你需要 elif(即 else if 的缩写)。

语法结构

if 条件1:
代码块1
elif 条件2:
代码块2
elif 条件3:
代码块3
...
else: # 可选,所有条件都不满足时执行
默认代码块

  • 从上到下依次检查每个条件。

  • 一旦某个条件为 True,就执行对应的代码块,然后跳出整个判断结构 ,不再检查后续的 elifelse

  • 如果没有条件为 True,且存在 else 块,则执行 else 块;否则什么都不做。

为什么要用 elif 而不是多个独立的 if

如果用多个独立的 if,每个条件都会独立判断,可能同时执行多个代码块(如果条件有重叠)。而 elif 保证了最多执行一个分支,这是互斥逻辑所需要的。

比如:

错误写法:

复制代码
score = 85
if score >= 60:
    print("及格")
if score >= 80:
    print("良好")
# 输出:及格\n良好

正确写法:

复制代码
if score >= 80:
    print("良好")
elif score >= 60:
    print("及格")
# 只输出一个

成绩等级示例

我们要实现:90分以上为A,80-89为B,70-79为C,60-69为D,60以下为F。

复制代码
score = 85
if score >= 90:
    grade = 'A'
elif score >= 80:
    grade = 'B'
elif score >= 70:
    grade = 'C'
elif score >= 60:
    grade = 'D'
else:
    grade = 'F'
print(f"等级:{grade}")

为什么顺序必须从高到低?

因为条件 score >= 80 其实包含了 score >= 90 的情况,如果把 >=80 写在前面,那么 95 分的同学会被错误地归入 B 等级。Python 执行时会先进入第一个满足的条件,因此必须从高到低写。

季节判断示例(多值匹配)

复制代码
month = 4
if month in (3, 4, 5):
    season = "春季"
elif month in (6, 7, 8):
    season = "夏季"
elif month in (9, 10, 11):
    season = "秋季"
elif month in (12, 1, 2):
    season = "冬季"
else:
    season = "无效月份"
print(season)

in 运算符让代码非常直观。

3.嵌套判断的替代方案

嵌套方法:

复制代码
if is_member:
    if spending >= 100:
        discount = 0.2
    else:
        discount = 0.1
else:
    discount = 0

优化为 and 逻辑(但这里因为有不同分支,可能不适用)。

另一种优化是提取内部判断为函数。但嵌套并不总是坏的,只要层级不超过 2~3 层且逻辑清晰,也可以接受。

推荐:使用 elifand 减少嵌套

复制代码
if is_member and spending >= 100:
    discount = 0.2
elif is_member:
    discount = 0.1
else:
    discount = 0

4. match-case 语句(Python 3.10+)----现代化的模式匹配

如果你曾接触过 C/C++ 的 switch-case,你会觉得 match-case 更强大也更优雅。它不仅能匹配具体的值,还能解构数据结构、添加守卫条件。

为什么需要 match-case

当你有大量基于单个变量值的等值判断时,if-elif 会变得冗长且重复:

复制代码
if status == 200:
    print("OK")
elif status == 404:
    print("Not Found")
elif status == 500:
    print("Server Error")
# ... 更多

match-case 更清晰:

复制代码
match status:
    case 200:
        print("OK")
    case 404:
        print("Not Found")
    case 500:
        print("Server Error")
    case _:
        print("Unknown")

基本要点

  • match 后面跟要匹配的表达式(通常是变量)。

  • case 后面跟一个模式(pattern),可以是字面量、变量名、解构模式等。

  • 使用 |(或)表示多个模式匹配同一个分支:case 500 | 502 | 503:

  • case _ 是通配符,匹配所有其他情况(类似 default)。

  • 匹配成功后执行对应的代码块,然后自动跳出 ,不需要**break**。

解构元组/列表

假设你有一个二维坐标点 (x, y),你想根据坐标值输出不同信息:

复制代码
point = (0, 0)
match point:
    case (0, 0):
        print("原点")
    case (x, 0):
        print(f"X轴上的点,x={x}")
    case (0, y):
        print(f"Y轴上的点,y={y}")
    case (x, y):
        print(f"普通点 ({x}, {y})")

这里 case (x, 0) 中的 x 是一个变量,它会自动捕获元组中第一个元素的值。注意:case (0, y) 中的 y 也是如此。这种模式解构非常强大。

守卫(guard)

有时匹配成功还需要额外的条件,比如"两个坐标相等"

复制代码
point = {0,0}
match point:
    case (x, y) if x == y:
        print("在对角线上")
    case (x, y):
        print(f"点 ({x}, {y})")

if x == y 就是守卫条件,只有模式匹配且守卫为真时才进入该分支。

使用 as 绑定整个匹配对象

复制代码
match items:
    case [first, second, *rest] as whole:
        print(f"第一个:{first},第二个:{second},剩余:{rest}")
        print(f"整个列表:{whole}")

as 可以把匹配到的对象赋值给一个变量,方便后续使用。

性能提示

match-case 并非简单的 if-elif 语法糖,它使用了更高效的跳转表(类似于 C 的 switch),当分支很多时性能优于 if-elif。但更重要的是可读性。

5.循环中的else子句

for 循环和 while 循环后面也可以跟一个 else 子句,它的行为与 if-else 完全不同。很多人第一次见到会困惑。

语法

**for item in iterable:

循环体

if condition:
break
else:

循环正常结束(没有被 break 打断)时执行**

while 类似。

判断列表是否包含奇数

复制代码
numbers = [2, 4, 6, 8]
for n in numbers:
    if n % 2 == 1:
        print("找到奇数")
        break
else:
    print("没有奇数")   # 因为循环正常结束,没有 break,所以执行这行

如果列表中有奇数,break 会触发,else 就不会执行。这完美地表达了"如果循环没有被提前终止,则执行此代码"。

经典用法:素数检测

复制代码
num = 17
for i in range(2, num):
    if num % i == 0:
        print(f"{num} 不是素数,因为能被 {i} 整除")
        break
else:
    print(f"{num} 是素数")

注意:不要与 if-else 混淆

  • if-else 是二选一,总是执行其中一个。

  • for-elseelse 只在循环没有被 break 终止时执行。如果循环从未执行(比如可迭代对象为空),else 也会执行(因为没有 break 发生)。

6.与循环配合的判断控制:breakcontinue

虽然不是判断语句本身,但它们与条件判断紧密配合,控制循环的流程。

  • break:立即结束整个循环,无论循环条件是否满足。

  • continue:跳过本次循环剩余代码,进入下一次迭代。

打印 1 到 10 之间的奇数

复制代码
for i in range(1, 11):
    if i % 2 == 0:
        continue   # 偶数跳过
    print(i)

输入数字,输入 0 退出

复制代码
while True:
    n = int(input("输入数字(0退出):"))
    if n == 0:
        break
    print(f"你输入了 {n}")

这个模式很常见:用 while True 配合 break 来构建"直到满足某个条件才退出"的循环。

7.复杂判断的性能优化技巧

当你的程序需要做很多判断时(比如一个函数里几十个 elif),性能可能会受影响。有以下几种优化方案:

1. 将最可能发生的分支放在前面

if-elif 是顺序判断的,如果能把高频条件放在前面,可以减少平均判断次数。

2. 使用字典映射取代长链 if-elif

当判断条件是等值比较(比如根据状态码执行不同操作)时,可以用字典存储"值->函数"的映射。

复制代码
def handle_200():
    print("OK")

def handle_404():
    print("Not Found")

def default_handler():
    print("Unknown")

handlers = {
    200: handle_200,
    404: handle_404,
}

status = 404
handlers.get(status, default_handler)()
  • handlers.get(status, default_handler) 返回 handlers[404],即函数对象 handle_404

  • 接着 () 调用该函数,打印 "Not Found"

如果 status 不在字典中(例如 500),则会返回 default_handler 并调用,输出 "Unknown"

  • ()函数调用运算符,它的作用是执行它前面的函数对象。

  • handlers.get(status, default_handler) 返回一个函数对象

    • 如果 status 是 200,返回 handle_200

    • 如果 status 是 404,返回 handle_404

    • 如果 status 是其他值(如 500),返回 default_handler

  • 然后 () 调用这个返回的函数。

所以 () 本身并不"代表"任何状态码 ,它只是负责执行查找到的函数。真正处理不同状态码的是 dict.get() 方法,它根据 status 返回对应的处理函数。

3. 使用 match-case(Python 3.10+)

如上所述,match-case 内部实现可能使用跳转表,对大量分支更高效。

4. 避免在循环内做复杂的判断

可以将判断移到循环外,或者使用向量化操作(如 NumPy)。

8.常见陷阱与最佳实践

陷阱 1:elif 条件顺序错误

如前所述,成绩判断必须从高到低,否则逻辑错误。季节判断则无顺序要求(因为月份互斥),但通常按自然顺序写。

陷阱 2:忘记写 case _ 导致无匹配时什么都不做

有时候你希望无匹配时抛出错误或给出提示,一定要写 case _

陷阱 3:在 match-case 中重复使用变量名导致覆盖

复制代码
match point:
    case (x, y):
        print(x, y)
    case (0, 0):   # 这里不会匹配,因为 (0,0) 已经被第一个 case 匹配,且 x=0,y=0
        print("origin")

case 的顺序也很重要,更具体的模式应放在前面。

陷阱 4:混淆 for-elseelse 的触发条件

很多初学者以为 else 在循环条件为假时执行,其实它是在循环没有被 break 终止时执行。如果循环被 break 打断,else 不会执行。

最佳实践:优先使用 match-case 而不是冗长的 if-elif

对于单个变量的等值匹配,match-case 可读性更好。但要注意 Python 版本必须 ≥ 3.10。

最佳实践:控制分支深度

如果一个函数里的 if-elif 超过 10 个,或者嵌套深度超过 3 层,应该考虑重构:使用字典映射、策略模式、或者将子逻辑提取为独立函数。

感谢你的观看,期待我们下次再见!

相关推荐
happymaker06261 小时前
MyBatis学习日记——DAY03(手写MyBatis框架实现简单功能)
学习
无敌的黑星星1 小时前
Java8 CompletableFuture 实战指南
linux·前端·python
山楂树の2 小时前
原生 WebGL + Canvas 实现鱼眼图像去畸变(Shader逐像素计算)
图像处理·数码相机·学习·程序人生
**蓝桉**2 小时前
容器服务学习笔记
笔记·学习
StockTV2 小时前
印度股票实时数据 NSE和BSE的实时行情、K 线及指数数据
java·开发语言·spring boot·python
chaofan9802 小时前
GPT-5.5 领衔 Image 2.0:像素级控制时代,AI 绘图告别开盲盒
开发语言·人工智能·python·gpt·自动化·api
乔代码嘚2 小时前
Agentic-KGR:多智能体强化学习驱动的知识图谱本体渐进式扩展技术
人工智能·学习·大模型·知识图谱·ai大模型·大模型学习·大模型教程
七颗糖很甜2 小时前
“十五五”气象发展规划:聚焦五大核心任务
大数据·python·算法
爱码小白2 小时前
Python 异常处理 完整学习笔记
开发语言·python