Python中match...case的用法
在C语言中有switch...case语句,Pthon3.10之前应该是没有类似语法,从Python3.10开始引入match...case与switch分支语句用法类似,但有细微差别,总结如下:
1.语法
肉眼可见的是关键词从switch变成了match,同时match...case语句遵循Python语法风格,如下:
switch(condition)
{case 1:do_something_1();break;case 2:do_something_2();break;case 3:do_something_3();break;default:do_default();
}
以上是C语言中switch...case的语法,需要注意:case后面需要有break,否则会继续执行下面的语句
match condition:case 1:do_something_1()case 2:do_something_2()case 3:do_something_3()case _:do_default()
以上是Python中match...case的语法,没有break,也没有default,取而代之的是捕捉模式(Capture),比如本例中的case _: ,与default功能类似,表示其他值,同时_相当于一个局部变量,其值等于condition,_也可以取其他变量名,当然,一个match语句中最多只能有一个捕捉模式的case,且必须位于最后一个case,就像只能有一个default一样
2.数据类型支持
C语言中的case后面只能是整形值,Python的case后面可以是大部分数据类型,对于不同数据类型的匹配规则,列举如下:
数值(int,float) & 字符串(string) & None:使用等号规则进行匹配
n = -1.2
match n:case 0: # 不匹配print("1")case 1: # 不匹配print("1")case 1.1: # 不匹配print("1.1")case 1.2: # 不匹配print("1.2")case "-1.2": # 不匹配print("str -1.2")case -1.2: # 匹配,且命中print("-1.2")case default: # 匹配,但未命中,因为前面case已经命中print("default = " + str(default))
s = '3'
print("s == num(3) ? " + str(s == 3))
match s:case 1: # 不匹配print("1")case 3: # 不匹配print("3")case "3": # 匹配,且命中print("str 3")case default: # 匹配,但未命中,因为前面case已经命中print("default" + default)
n = None
match n:case 0: # 不匹配print("0")case "": # 不匹配print('""')case False: # 不匹配print("False")case None: # 匹配,且命中print("None")case default: # 匹配,当未命中,因为前面case已经命中print("default" + str(default))
布尔值(Boolean):比较特殊,True会匹配True和数字1,False会匹配False和数字0
b = True
match b:case "": # 不匹配print('""')case 0: # 不匹配print("0")case 11: # 不匹配print(11)case 1: # 匹配,且命中print(1)case True: # 匹配,但未命中,因为前面case已经命中print(True)case False: # 不匹配print(False)case default: # 匹配,但未命中,因为前面case已经命中print("default = " + str(default))
b = False
match b:case "": # 不匹配print('""')case 0: # 匹配,且命中print("0")case 11: # 不匹配print(11)case 1: # 不匹配print(1)case True: # 不匹配print(True)case False: # 匹配,但未命中,因为前面case已经命中print(False)case default: # 匹配,但未命中,因为前面case已经命中print("default = " + str(default))
字典(dictionary):当condition是个字典时,case后面只要是字典,且case后面字典的键值对在condition中都能找到,则该case命中,键值对无顺序要求,有一个比较特殊情况,假如case后面跟的是空字典,那么不管condition字典内容是什么,该case必然命中
a = {"ab":3, "5":5}
match a:case 1: # 不匹配print("1")case {"ab":2}: # 不匹配print("ab2")case {"ab":1}: # 不匹配print("ab1")case {"c":3}: # 不匹配print("c3")case {"5":5, "ab":3}: # 匹配,且命中print("5:5 ab:3")case {"ab":3, "t":3}: # 不匹配print("ab3 t3")case {"ab":3, "5":4}: # 不匹配print("ab3 5:4")case {"ab":3, "5":5, "t":2}: # 不匹配print("ab3 5:5 t2")case {"ab":3, "5":5}: # 匹配,但未命中,因为前面case已经命中print("ab3 5:5")case {"ab":3}: # 匹配,但未命中,因为前面case已经命中print("ab3")case {}: # 匹配,但未命中,因为前面case已经命中print("{}")case _b: # 匹配,但未命中,因为前面case已经命中print("_______" + str(_b))
列表 (list)& 元组(tuple):当condition是个列表或元组时,在做case比对时不分列表和元组,只要元素数量相同,且每个索引位置值相同,即可匹配成功
l = [2,3,4,5]
match l:case 2: # 未匹配print("2")case 2,3: # 未匹配print("2,3")case 2,3,4,5,6: # 未匹配print("2,3,4,5,6")case [2,4,3,5]: # 未匹配print("[2,4,3,5]")case (2,4,3,5): # 未匹配print("(2,4,3,5)")case (2,3,4,5): # 匹配,且命中print("(2,3,4,5)")case [2,3,4,5]: # 匹配,但未命中,因为已经命中了前面的caseprint("[2,3,4,5]")case default: # 匹配,但未命中,因为已经命中了前面的caseprint("default = " + str(type(default)) + str(default))
集合(set):目前似乎还不支持集合数据类型的匹配(不确定,如有错误之处,望留言指正)
类(Class):首先判断是否属于同一个class,然后判断calss各属性值是否相等
class Point:def __init__(self, x, y):self.x = xself.y = y
class Point2:def __init__(self, x, y):self.x = xself.y = yobj = Point(1,2)
match obj:case Point(x=3, y=4): # 不匹配,属性值不相等print("Point,3,4")case Point2(x=1, y=2): # 不匹配,class类型不一致print("Point2,1,2")case {"x":1, "y":2}: # 不匹配,Class类型不一致print("{x,y}")case Point(x=1, y=2): # 匹配,且命中print("Point,1,2")case default:print("default=" + str(default))
3.组合case
在C语言中,可以多个case对应一个执行过程,如下所示
switch(condition)
{case 1:do_something_1();break;case 2:case 3:do_something_2_3();break;case 4:case 5:do_something_4_5();break;default:do_default();
}
当condition等于2或3时,执行do_sometion_2_3()函数,当condition等于4或5时,执行do_something_4_5()函数
在Python中也有类似写法,叫作组合(OR)模式,如下所示
c = 5
match c:case 1: # 不匹配print("1")case 1 | 2: # 不匹配print("1 | 2")case 3 | 4: # 不匹配print("3 | 4")case 5 | 6 | 7: # 匹配,且命中print("5 | 6 | 7")case 5: # 匹配,但未命中,因为前面case已经命中print("5")case _: # 匹配,但未命中,因为前面case已经命中print("default = " + str(_))
4.通配符,捕捉模式的扩展
当捕捉模式应用到列表和字典等复杂数据类型时,情况会比较复杂,我们通过几个例子来进行说明
d = [1,2,3,4]
match d:case a,b: # 不匹配,元素数量不等print("a,b")print([a,b])case a,b,c: # 不匹配,元素数量不等print("a,b,c")print([a,b,c,d])case 2,*b: # 不匹配,索引位值不相等,其中*b代表任意个元素print("2,*b")print(b)case 1,*b,3: # 不匹配,索引位值不相等print("1,*b,3")print(b)case *b,2: # 不匹配,索引位值不相等print("*b,2")print(b)case 1,2,3,*b,4: # 匹配,且命中print("1,2,3,*b,4")print(b) // b = []case 1,*b,4: # 匹配,但未命中,因为前面case已命中print("1,*b,4")print(b)case *b,4: # 匹配,但未命中,因为前面case已命中print("*b,4")print(b)case 1,*b: # 匹配,但未命中,因为前面case已命中print("1,*b")print(b)case *b,: # 匹配,但未命中,因为前面case已命中print("*b,")print(b)case [*b]: # 匹配,但未命中,因为前面case已命中print("[*b]")print(b)case 2,b,c,d: # 不匹配,索引位值不相等print("2,b,c,d")print([2,b,c,d])case 1,2,c,d: # 匹配,但未命中,因为前面case已命中print("1,2,c,d")print([1,2,c,d])case 1,b,c,d: # 匹配,但未命中,因为前面case已命中print("1,b,c,d")print([1,b,c,d])case a,b,c,d: # 匹配,但未命中,因为前面case已命中print("a,b,c,d")print([a,b,c,d])case _: # 匹配,但未命中,因为前面case已命中print("_")
本例中的a,b,c,d为捕捉模式在列表中的应用,而*b为通配符,表示匹配任意个元素,包括0个元素,且一个case中只能有一个通配符变量
类似地,捕捉模式和通配符还可以应用到字典数据类型,如下
d = {"a":1, "b":"bb", "c": [3,4], "d": {"dd":5}}
match d:case {"s": 1}: # 不匹配print("s:1")case {"a":a}: # 匹配,且命中print("a:a")print(a) # a=1case {"b":bbb}: # 匹配,但未命中,因为前面case已经命中print("b:bbb")print(bbb) # bbb = "bb"case {"a":1, **p}: # 匹配,但未命中,因为前面case已经命中print("a:1:**p")print(p) # p = {"b":"bb", "c": [3,4], "d": {"dd":5}}case {**p}: # 匹配,但未命中,因为前面case已经命中print("**p")print(p) # p = {"a":1, "b":"bb", "c": [3,4], "d": {"dd":5}}case {"d":d, **p}: # 匹配,但未命中,因为前面case已经命中print("d:d:**p")print(p) # p = {"a":1, "b":"bb", "c": [3,4]}case _: # 匹配,但未命中,因为前面case已经命中print("default=" + str(default)) # default = d = {"a":1, "b":"bb", "c": [3,4], "d": {"dd":5}}
倘若要将捕捉模式和通配符用于自定义类,需要给自定义类定义一个__match_args__数组,如下
class Point:__match_args__ = ('x', 'y')def __init__(self, x, y):self.x = xself.y = y
或者使用标准库的dataclasses.dataclass装饰器,它会提供__match_args__属性,如下
from dataclasses import dataclass@dataclass
class Point2:x: inty: int
这样就可以使用捕捉模式,如下
class Point:__match_args__ = ('x', 'y')def __init__(self, x, y):self.x = xself.y = yfrom dataclasses import dataclass@dataclass
class Point2:x: inty: intobj = Point2(1,2)
match obj:case Point(x, y): # 不匹配,Class类型不一致print(f'Point({x=},{y=})')case Point2(x, y): # 匹配,且命中print(f'Point2({x=},{y=})')case Point(x=3, y=4): # 不匹配,Class类型不一致print("Point,3,4")case Point2(x=1, y=2): # 匹配,但未命中,因为前面case已经命中print("Point2,1,2")case {"x":1, "y":2}: # 不匹配,Class类型不一致print("{x,y}")case Point(x=1, y=2): # 不匹配,Class类型不一致print("Point,1,2")case default:# 匹配,但未命中,因为前面case已经命中print("default=" + str(default))
5.数据类型匹配
简单来说就是只根据数据类型来判断是否匹配,如下
a = {1,2,3}
match a:# case object():# print("object")case int(): # 不匹配print("int")case str(): # 不匹配print("str")case list(): # 不匹配print("list")case tuple(): # 不匹配print("tuple")case dict(): # 不匹配print("dict")case set(): # 匹配,命中print("set")case bool(): # 不匹配print("bool")case default:print("default=" + str(type(default)) + str(default))
需要注意的是True和False会匹配int()和bool(),所有值都会匹配object
6.AS语法
简单来说就是当匹配某个case时,将匹配到的值存入用as语句声明的新变量中,通常和数据类型匹配相结合使用,如下
a = [1,2,3,"4"]
match a:case {"b": bb} as v: # 不匹配print("b:bb:v")print(bb)print(v)case [1, *b, int() as v]: # 不匹配print("[1, *b]:int,v")print(b)print(v)case [1, *b, str() as v]: # 匹配,命中print("[1, *b]:str,v")print(b) # b = [2,3]print(v) # v = "4"case _:print("default = " + str(type(default)) + str(default))
7.补充条件模式
可以在case后面使用if语句来添加匹配的判断条件,如下
a = [3, 4, 5, 6]
match a:case [a, *b, c] if a>10: # 不匹配,a不大于10print("a>10")print("c=" + str(c))case [a, *b, c] if a>5: # 不匹配print("10>a>5")print("c=" + str(c))case [a, *b, c] if a>0: # 匹配print("5>a>0")print("c=" + str(c)) # c = 6case [a, *b, c] if a<0: # 不匹配print("a<0")print("c=" + str(c))case _:print("a=0")
再比如
cmd = ["go", "away"]
match cmd:case ["go", dir] if dir in ["east", "west"]: # 不匹配print("go->" + dir)case ["go", dir] if dir == "north" or dir == "south": # 不匹配print("stop")case ["go", dir]: # 匹配,命中print("unknown dir:" + dir)case _:print("default")
相关文章:
Python中match...case的用法
在C语言中有switch...case语句,Pthon3.10之前应该是没有类似语法,从Python3.10开始引入match...case与switch分支语句用法类似,但有细微差别,总结如下: 1.语法 肉眼可见的是关键词从switch变成了match,同…...
深度学习自学笔记二:逻辑回归和梯度下降法
目录 一、逻辑回归 二、逻辑回归的代价函数 三、梯度下降法 一、逻辑回归 逻辑回归是一种常用的二分类算法,用于将输入数据映射到一个概率输出,表示为属于某个类别的概率。它基于线性回归模型,并使用了sigmoid函数作为激活函数。 假设我们…...
【Element】通知 Notification
ElementUI 弹出通知 created() {const h this.$createElementconst that thisthis.$notify({onClose: function () {that.do()},type: warning,duration: 5000, // 5秒后隐藏offset: 0, // 距离顶部dangerouslyUseHTMLString: false, showClose: false,customClass: notify-…...
vue+express、gitee pm2部署轻量服务器(20230923)
一、代码配置 前后端接口都保持 127.0.0.1:3000 vue 项目 创建文件 pm2.config.cjs module.exports {apps: [{name: xin-web, // 应用程序的名称script: npm, // 启动脚本args: run dev, // 启动脚本的参数cwd: /home/vue/xin_web, // Vite 项目的根目录interpreter: none,…...
前端教程-H5游戏开发
Egret EGRETIA RC 版本正式发布 从端到云一站式区块链游戏开发工作流 官网 Laya Air 在渲染模式上,LayaAir 支持 Canvas 和 WebGL 两种方式;在工具流的支持程度上,主要是提供了 LayaAir IDE。LayaAir IDE 包括代码模式与设计模式ÿ…...
Nginx 关闭/屏蔽 PUT、DELETE、OPTIONS 请求
1、修改 nginx 配置 在 nginx 配置文件中,增加如下配置内容: if ($request_method !~* GET|POST|HEAD) {return 403; }修改效果如下: 2、重启 nginx 服务 systemctl restart nginx或者 service nginx restart3、功能验证 使用如下方式…...
【React】React概念、特点和Jsx基础语法
React是什么? React 是一个用于构建用户界面的 JavaScript 库。 是一个将数据渲染为 HTML 视图的开源 JS 库它遵循基于组件的方法,有助于构建可重用的 UI 组件它用于开发复杂的交互式的 web 和移动 UI React有什么特点 使用虚拟 DOM 而不是真正的 DO…...
大数据的崭露头角:数据湖与数据仓库的融合之道
文章目录 数据湖与数据仓库的基本概念数据湖(Data Lake)数据仓库(Data Warehouse) 数据湖和数据仓库的优势和劣势数据湖的优势数据湖的劣势数据仓库的优势数据仓库的劣势 数据湖与数据仓库的融合之道1. 数据分类和标记2. 元数据管…...
用go实现cors中间件
目录 一、概述 二、简单请求和预检请求 简单请求 预检请求 三、使用go的gin框架实现cors配置 1、安装 2、函数 一、概述 CORS(Cross-Origin Resource Sharing)是一种浏览器安全机制,用于控制在Web应用程序中不同源(Origin&a…...
Linux 链表示例 LIST_INIT LIST_INSERT_HEAD
list(3) — Linux manual page 用Visual Studio 2022创建CMake项目 * CmakeLists.txt # CMakeList.txt : Top-level CMake project file, do global configuration # and include sub-projects here. # cmake_minimum_required (VERSION 3.12)project ("llist")# I…...
【机器学习】详解回归(Regression)
文章目录 是什么的问题案例说明 是什么的问题 回归分析(Regression Analysis) 是研究自变量与因变量之间数量变化关系的一种分析方法,它主要是通过因变量Y与影响它的自变量 X i ( i 1 , 2 , 3 … ) X_i(i1…...
mac 配置 httpd nginx php-fpm 详细记录 已解决
在日常mac电脑 开发php项目一直是 httpd 方式 运行,由于有 多版本 运行的需求,docker不想用,索性用 php-fpm进行 功能处理。上次配置 是好的,但是感觉马马虎虎,这次 配置底朝天。因为配置服务器,几乎也都是…...
Angular 项目升级需要注意什么?
升级Angular项目是一个重要的任务,因为它可以帮助你获得新的功能、性能改进和安全性增强。然而,Angular的版本升级可能会涉及到一些潜在的问题和挑战。以下是升级Angular项目时需要注意的一些重要事项: 备份项目:在升级之前&…...
开发高性能知识付费平台:关键技术策略
引言 在构建知识付费平台时,高性能是确保用户满意度和平台成功的关键因素之一。本文将探讨一些关键的技术策略,帮助开发者打造高性能的知识付费平台。 1. 前端性能优化 使用CDN加速资源加载 使用内容分发网络(CDN)来托管和加…...
python图像匹配:如何使用Python进行图像匹配
Python图像匹配是指使用Python编写的程序来进行图像匹配。它可以在两幅图像之间找到相似的部分,从而实现图像检索、图像比较、图像拼接等功能。 Python图像匹配是指使用Python编写的程序来进行图像匹配。它可以在两幅图像之间找到相似的部分,从而实现图…...
R语言绘制PCA双标图、碎石图、变量载荷图和变量贡献图
1、原论文数据双标图 代码: setwd("D:/Desktop/0000/R") #更改路径#导入数据 df <- read.table("Input data.csv", header T, sep ",")# ----------------------------------- #所需的包: packages <- c("ggplot2&quo…...
Jolokia 笔记 (Kafka/start/stop)
目录 1. Jolokia 笔记 (Kafka/start/stop) 1. Jolokia 笔记 (Kafka/start/stop) java -javaagent:agent.jarport8778,hostlocalhostJolokia 是作为 Kafka 的 Java agent, 基于 HTTP 协议提供了一个使用 JSON 作为数据格式的外部接口, 提供给 DataKit 使用。 Kafka 启动时, 先配…...
Qt5开发及实例V2.0-第十九章-Qt.QML编程基础
Qt5开发及实例V2.0-第十九章-Qt.QML编程基础 第19章 QML编程基础19.1 QML概述19.1.1 第一个QML程序19.1.2 QML文档构成19.1.3 QML基本语法 19.2 QML可视元素19.2.1 Rectangle(矩形)元素19.2.2 Image(图像)元素19.2.3 Text…...
固定开发板的ifconfig的IP地址
背景 由于我是使用vsocode的ssh插件远程连接我的开发板, 所以我每次开机就要重新连上屏幕看一下这个ifconfig的ip地址然后更改我的ssh config文件 这里提供一个使用nmcli设置静态IP的方法 请确保使用你的实际连接名称替换Wi-Fi connection 1 使用nmcli设置静态IP相对直接&a…...
停车场系统源码
源码下载地址(小程序开源地址):停车场系统小程序,新能源电动车充电系统,智慧社区物业人脸门禁小程序: 【涵盖内容】:城市智慧停车系统,汽车新能源充电,两轮电动车充电,物…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
