Skip to main content

Python 基础

Python 条件判断与模式匹配

本章节将深入讲解 Python 中的条件判断和模式匹配。我们将从基本的条件判断开始,逐步过渡到 Python 3.10 引入的模式匹配(match 语句),最后探讨复杂模式匹配及其优点。

1. 基本的条件判断(if 语句)

条件判断是编程中最基础的控制流结构,用于根据条件执行不同的代码块。Python 使用 ifelifelse 关键字实现条件判断。以下是基本语法:

condition = True
if condition:
    print("条件为真,执行此代码块")
else:
    print("条件为假,执行此代码块")

1.1 单条件判断

最简单的 if 语句检查一个条件是否为真:

age = 18
if age >= 18:
    print("你已成年!")
else:
    print("你未成年!")

输出:

你已成年!

1.2 多条件判断

使用 elif 可以检查多个条件,else 处理剩余情况:

score = 85
if score >= 90:
    print("优秀")
elif score >= 80:
    print("良好")
elif score >= 60:
    print("及格")
else:
    print("不及格")

输出:

良好

1.3 嵌套条件判断

可以在 if 语句中嵌套另一个 if 语句,但过多的嵌套会降低代码可读性:

number = 10
if number > 0:
    if number % 2 == 0:
        print("正偶数")
    else:
        print("正奇数")
else:
    print("非正数")

输出:

正偶数

1.4 逻辑运算符

使用 andornot 组合多个条件:

temperature = 25
is_sunny = True
if temperature > 20 and is_sunny:
    print("适合户外活动!")
else:
    print("建议室内活动。")

输出:

适合户外活动!

要点

  • 条件表达式必须返回布尔值(TrueFalse)。
  • 使用缩进(通常 4 个空格)定义代码块。
  • elifelse 是可选的。

2. 模式匹配(match 语句)

Python 3.10 引入了结构化模式匹配(match 语句),提供了一种更直观的方式处理复杂条件逻辑。它类似于其他语言的 switch 语句,但功能更强大,支持匹配值、数据结构和类型。

  • Python 的 match 语句在匹配到一个 case 后会立即退出,不会继续匹配后续分支,与 Java 传统 switch 的“贯穿”行为不同。
  • 教程中使用 return 是为了示例简洁,但 case 分支可以包含任意代码,不限于返回值。

2.1 基本模式匹配

match 语句的基本语法如下:

def get_day_name(day):
    match day:
        case 1:
            return "星期一"
        case 2:
            return "星期二"
        case 3:
            return "星期三"
        case _:
            return "无效日期"

print(get_day_name(1))

输出:

星期一
  • case _ 是默认分支,类似 else,没有匹配任何值的情况走此分支。
  • 每个 case 分支可以直接返回值,简化代码。

2.2 匹配列表和元组

模式匹配可以解构列表或元组,检查其结构和内容:

def process_command(command):
    match command:
        case ["start"]:
            return "启动系统"
        case ["stop"]:
            return "停止系统"
        case ["move", direction]:
            return f"向 {direction} 移动"
        case _:
            return "未知命令"

print(process_command(["move", "left"]))

输出:

向 left 移动
  • case ["move", direction] 捕获第二个元素到变量 direction
  • 匹配顺序很重要,Python 会从上到下尝试每个 case

2.3 匹配字典

模式匹配也可以处理字典,检查键值对:

def handle_response(response):
    match response:
        case {"status": "success", "data": data}:
            return f"成功,数据:{data}"
        case {"status": "error", "message": msg}:
            return f"错误:{msg}"
        case _:
            return "无效响应"

print(handle_response({"status": "success", "data": [1, 2, 3]}))

输出:

成功,数据:[1, 2, 3]
  • 字典模式匹配只检查指定的键,未指定的键被忽略。
  • 变量(如 data)捕获对应的值。

3. 复杂的模式匹配

模式匹配的真正威力在于处理复杂数据结构,例如嵌套结构、类型检查和条件守卫。

3.1 嵌套模式匹配

可以匹配嵌套的数据结构,例如列表中的列表:

def analyze_data(data):
    match data:
        case [int(x), [str(s), int(y)]]:
            return f"整数 {x},嵌套字符串 {s} 和整数 {y}"
        case [float(x), _]:
            return f"浮点数 {x}"
        case _:
            return "无法识别的数据"

print(analyze_data([42, ["hello", 100]]))

输出:

整数 42,嵌套字符串 hello 和整数 100
  • int(x) 确保第一个元素是整数并捕获其值。
  • [str(s), int(y)] 匹配嵌套列表的结构。
  • 注意:这里的 int(x) 不是类型转换,是指定类型。

3.2 使用条件守卫

if 守卫可以在 case 中添加额外条件:

def check_point(point):
    match point:
        case (x, y) if x == y:
            return "点在对角线上"
        case (x, y) if x > 0 and y > 0:
            return "点在第一象限"
        case _:
            return "其他位置"

print(check_point((3, 3)))

输出:

点在对角线上
  • if x == y 是一个守卫,只有当条件满足时才匹配该 case

3.3 匹配类和对象

模式匹配可以检查对象的类型和属性:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

def describe_person(person):
    match person:
        case Person(name=name, age=age) if age >= 18:
            return f"{name} 是成年人"
        case Person(name=name):
            return f"{name} 是未成年人"
        case _:
            return "无效对象"

person = Person("Alice", 25)
print(describe_person(person))

输出:

Alice 是成年人
  • Person(name=name, age=age) 解构对象的属性并捕获值,并不是创建实例。
  • 守卫 if age >= 18 添加额外条件。

4. 模式匹配的优点

模式匹配相较于传统 if 语句有以下优点:

  1. 可读性强:模式匹配将复杂逻辑分解为清晰的 case 分支,减少嵌套 if 语句,提高代码可读性。
  2. 表达力强:支持匹配值、结构、类型和条件守卫,能处理复杂的逻辑场景。
  3. 简洁性:通过解构和捕获变量,减少手动解析数据结构的代码。
  4. 安全性:模式匹配确保所有可能情况都被处理(通过 case _),降低遗漏逻辑的错误。
  5. 灵活性:支持嵌套结构和类匹配,适合处理复杂数据,如 JSON 或 API 响应。

示例对比:以下是用 ifmatch 处理相同逻辑的对比:

# 使用 if
def process_status(status):
    if isinstance(status, dict) and status.get("status") == "success":
        return f"成功,数据:{status.get('data')}"
    elif isinstance(status, dict) and status.get("status") == "error":
        return f"错误:{status.get('message')}"
    else:
        return "无效响应"

# 使用 match
def process_status_match(status):
    match status:
        case {"status": "success", "data": data}:
            return f"成功,数据:{data}"
        case {"status": "error", "message": msg}:
            return f"错误:{msg}"
        case _:
            return "无效响应"

print(process_status_match({"status": "success", "data": [1, 2, 3]}))

输出:

成功,数据:[1, 2, 3]

match 版本更简洁直观,逻辑清晰,易于维护。

5. 总结

  • 条件判断if 语句适合简单逻辑,结合逻辑运算符和嵌套可以处理较复杂场景,但代码可能变得冗长。
  • 模式匹配match 语句适合处理复杂数据结构,语法简洁,表达力强,适合现代 Python 开发。
  • 学习建议:初学者应先掌握 if 语句,确保理解基本逻辑控制;熟练后学习 match 语句,处理复杂场景如 API 数据解析或嵌套结构。