Python 中的结构模式匹配

news/2024/11/30 7:45:47/

文章目录

    • 结构模式匹配简介及其重要性
    • 在 Python 中使用结构模式匹配
      • match ... case 语句的基本使用
      • 使用 match ... case 来检测和解构数据结构
      • 使用 match ... case 与捕获模式和序列模式
      • 使用 match ... case 和通配符模式
      • 在类模式中使用 match ... case
      • 使用 match ... case 和 OR 模式
      • 将 match ... case 与文字模式一起使用


在 Python 3.10 之前,我们没有任何内置的方式来使用结构模式匹配,在其他编程语言中称为 switch-case。 从 Python 3.10 版本开始,我们不能使用 match ... case 语句来模拟 switch ... case 语句。

本篇文章介绍结构模式匹配及其在 Python 中的重要性。 它还使用不同的模式来演示如何使用 match … case 语句。


结构模式匹配简介及其重要性

截至 2021 年初,我们无法在低于或等于 3.9 的已发布 Python 版本中使用 match 关键字。 那时,我们习惯于使用字典或嵌套的 if/elif/else 语句来模拟 switch ... case

但是,Python 3.10 引入了一个新特性,称为结构模式匹配(match ... case 语句)。 它相当于我们在 Java、C++ 和许多其他编程语言中使用的 switch ... case 语句。

这一新功能使我们能够编写简单、易于阅读且最不容易出错的流程控制语句。


在 Python 中使用结构模式匹配

结构模式匹配用作 switch … case 语句,比这更强大。 如何? 让我们探索下面的一些示例,以了解它们在不同情况下的用途。

match … case 语句的基本使用

示例代码:

colour = "blue"
match colour:case "green":print("The specified colour is green")case "white":print("Wow, you've picked white")case "green":print("Great, you are going with green colour")case "blue":print("Blue like sky...")

输出:

Blue like sky...

在这里,我们首先有一个包含蓝色的可变颜色。 然后,我们使用 match 关键字,它将颜色变量的值与各种指定的案例进行匹配,其中每个案例都以 case 关键字开头,后跟我们要比较或检查的模式。

模式可以是以下之一:

  • 文本模式
  • 捕获模式
  • 通配符模式
  • 定值模式
  • 序列模式
  • 映射模式
  • 类模式
  • 或模式
  • walrus 模式

match ... case 语句只运行第一个匹配的 case 下的代码。

如果没有匹配到 case 怎么办? 用户将如何知道它? 为此,我们可以有一个默认情况,如下所示。

示例代码:

colour = "yellow"
match colour:case "green":print("The specified colour is green")case "white":print("Wow, you've picked white")case "green":print("Great, you are going with green colour")case "blue":print("Blue like sky...")case other:print("No match found!")

输出:

No match found!

使用 match … case 来检测和解构数据结构

示例代码:

student = {"name": {"first": "Mehvish", "last": "Ashiq"},"section": "B"
}match student:case {"name": {"first": firstname}}:print(firstname)

输出:

Mehvish

在上面的示例中,结构模式匹配在以下两行代码中起作用:

match student:case {"name": {"first": firstname}}:

我们使用 match … case 语句通过从学生数据结构中提取学生的名字来找到它。 在这里,student 是一个包含学生信息的字典。

案例行指定我们的模式来匹配学生。 考虑到上面的例子,我们寻找一个带有“name”键的字典,其值为一个新字典。

这个嵌套字典包含一个“first”键,其值绑定到 firstname 变量。 最后,我们使用 firstname 变量来打印值。

如果您更深入地观察它,我们已经了解了这里的映射模式。 如何? 映射模式看起来像 {"student": s, "emails": [*es]},它匹配映射与至少一组指定的键。

如果所有子模式都匹配它们对应的值,那么它将在与键对应的值匹配期间绑定任何子模式绑定。 如果我们想要允许捕获额外的项目,我们可以在模式的末尾添加 **rest。

使用 match … case 与捕获模式和序列模式

示例代码:

def sum_list_of_numbers(numbers):match numbers:case []:return 0case [first, *rest]:return first + sum_list_of_numbers(rest)sum_list_of_numbers([1,2,3,4])

输出:

10

这里,我们使用递归函数,使用捕获模式捕获到指定模式的匹配,并绑定到名字上。

在此代码示例中,如果第一种情况与空列表匹配,则第一种情况返回 0 作为总和。 第二种情况使用带有两个捕获模式的序列模式来匹配列表与多个项目/元素之一。

在这里,列表中的第一项被捕获并绑定到名字,而第二个捕获模式 *rest 使用解包语法来匹配任意数量的项目/元素。

%> 请注意 ,其余部分绑定到包含数字的所有项目/元素的列表,不包括第一个。 为了获得输出,我们通过传递上面给出的数字列表来调用 sum_list_of_numbers() 函数。

使用 match … case 和通配符模式

示例代码:

def sum_list_of_numbers(numbers):match numbers:case []:return 0case [first, *rest]:return first + sum_list_of_numbers(rest)case _:incorrect_type = numbers.__class__.__name__raise ValueError(f"Incorrect Values. We Can only Add lists of numbers,not {incorrect_type!r}")sum_list_of_numbers({'1':'2','3':'4'})

输出:

ValueError: Incorrect Values. We Can only Add lists of numbers, not 'dict'

我们在学习 match ... case 语句的基本用法时学习了使用通配符模式的概念,但没有在那里介绍通配符模式术语。 想象一下前两种情况不匹配的情况,我们需要一个 catchall 模式作为我们的最终情况。

例如,如果我们得到任何其他类型的数据结构而不是列表,我们希望引发错误。 在这里,我们可以使用 _ 作为通配符模式,它将匹配任何内容而不绑定到名称。 我们在最后一个案例中添加错误处理以通知用户。

你怎么说? 我们的模式适合搭配吗? 让我们通过传递字符串值列表来调用 sum_list_of_numbers() 函数来测试它,如下所示:

sum_list_of_numbers(['1','2','3','4'])

它将产生以下错误:

TypeError: can only concatenate str (not "int") to str

因此,我们可以说该模式仍然不够万无一失。 为什么? 因为我们将列表类型数据结构传递给 sum_list_of_numbers() 函数,但具有字符串类型值,而不是我们预期的 int 类型。

请参阅以下部分以了解如何解决它。

在类模式中使用 match … case

示例代码:

def sum_list_of_numbers(numbers):match numbers:case []:return 0case [int(first), *rest]:return first + sum_list_of_numbers(rest)case _:raise ValueError(f"Incorrect values! We can only add lists of numbers")sum_list_of_numbers(['1','2','3','4'])

输出:

ValueError: Incorrect values! We can only add lists of numbers

基本情况(第一种情况)返回 0; 因此,求和仅适用于我们可以用数字相加的类型。 请注意,Python 不知道如何添加文本字符串和数字。

所以,我们可以使用类模式来限制我们的模式只匹配整数。 类模式类似于映射模式,但匹配属性而不是键。

使用 match … case 和 OR 模式

示例代码:

def sum_list_of_numbers(numbers):match numbers:case []:return 0case [int(first) | float(first), *rest]:return first + sum_list_of_numbers(rest)case _:raise ValueError(f"Incorrect values! We can only add lists of numbers")

假设我们想让 sum_list_of_numbers() 函数用于值列表,无论是 int 类型还是 float 类型的值。 我们使用用竖线符号 (|) 表示的 OR 模式。

如果指定列表包含 int 或 float 类型值以外的值,则上述代码必须引发 ValueError。 让我们考虑以下所有三种情况进行测试。

测试 1:传递具有 int 类型值的列表:

sum_list_of_numbers([1,2,3,4]) #output is 10

测试 2:传递具有 float 类型值的列表:

sum_list_of_numbers([1.0,2.0,3.0,4.0]) #output is 10.0

测试 3:传递具有除 intfloat 类型之外的任何其他类型的列表:

sum_list_of_numbers(['1','2','3','4'])
#output is ValueError: Incorrect values! We can only add lists of numbers

如您所见,由于使用了 OR 模式,sum_list_of_numbers() 函数适用于 int 和 float 类型的值。

将 match … case 与文字模式一起使用

示例代码:

def say_hello(name):match name:case "Mehvish":print(f"Hi, {name}!")case _:print("Howdy, stranger!")
say_hello("Mehvish")

输出:

Hi, Mehvish!

此示例使用与文字对象匹配的文字模式,例如,显式数字或字符串,正如我们在学习 match ... case 语句的基本用法时所做的那样。

它是最基本的模式类型,让我们模拟一个类似于 Java、C++ 和其他编程语言的 switch ... case 语句。 您可以访问此页面以了解所有模式。


http://www.ppmy.cn/news/414596.html

相关文章

AIGC 加持 Cocos,游戏开发需要几步?

近日,游戏行业知名的 B2B 大会 WN 2023 大会于土耳其首都伊斯坦布尔顺利举办。本次大会邀请了来自全球的游戏开发商、媒体、发行商、分发平台等行业决策者,共同探讨游戏行业未来发展态势,进一步拓展业务,并在世界范围内寻找新的合…

智驾传感器新风向!拐点将至

“大家都比较关注激光雷达,尤其是在今年整个行业聚焦降本的大背景下,这个赛道还行不行?”6月8日,2023年度(第十四届)高工智能汽车开发者大会上,高工智能汽车研究院首发《2023-2025年中国汽车市场…

华为认证 | HCIA-SDN 考试大纲

01 考试概述 02 考试范围 HCIA-SDN V1.0考试覆盖数据通信基础知识,SDN架构,SDN二、三层网络原理,SDN接口协议原理比如OpenFlow协议、Netconf协议、RestFul协议原理,以及在华为交换机与路由器中的实现。 SDN二三层技术&#xff1…

Ubuntu显示设置

作者 QQ群:852283276 微信:arm80x86 微信公众号:青儿创客基地 B站:主页 https://space.bilibili.com/208826118 参考 linux系统配置x11,配置Xorg X11窗口系统 恢复ubuntu20.04默认桌面管理器 Ubuntu18.04多显卡配置显示输出&…

安装Ubuntu 18.04卡死问题记录

新机安装 ubuntu 出现卡死问题,本篇做下记录 由于本机没有核显,独显又是 nvidia GT710,起初猜测跟显卡有关,网上也有许多相关问题的解决实例,具体步骤如下: BIOS关闭安全启动模式进入grub,按键…

计算机屏幕出现GT,传奇亮机卡GT710又诈尸?这次居然可同时带16个显示器

[PConline 杂谈]近日,华硕在其官网上架了型号为GT710-4H-SL-2GD5的新显卡,售价预计在400人民币以内,要知道GT710自首发伊始定位就是一张“亮机卡”,公版的性能甚至不如主流核显,在该GPU首发4年后厂商居然还为其推出新品…

CVPR 2023 | 美团技术团队精选论文解读

本文精选了美团技术团队被CVPR 2023收录的8篇论文进行解读。这些论文既有自监督学习、领域自适应、联邦学习等通用学习范式方面的技术迭代,也涉及目标检测、跟踪、分割、Low-level Vision等典型视觉任务的性能,体现了美团在基础通用技术和垂直领域技术上…

电脑重启bootmgr_解决电脑出现bootmgr is missing如何解决

bootmgr is missing翻译为引导丢失,是一种常见的黑屏现象,很多朋友看到bootmgr is missing问题就束手无策,其实我们可以通过下面三种方法来排除解决。有需要就一起来了解一下吧 今天早上开机电脑就出现bootmgr is missing,这是什么东东,怎么进系统?遇见这种情况小编深表同…