前言
本文主要介绍match-case语句与switch-case的区别,及match-case语句的基本用法。
文章目录
- 前言
- 一、switch-case 和match-case的区别
- 二、match-case的基本用法
- 1、可匹配的数据类型
- 2、多条件匹配
- 3、通配符匹配
一、switch-case 和match-case的区别
C语言里面switch-case所匹配的变量类型只能是整数型或者字符型,而Python里的match-case数据类型(对象类型)丰富多彩,可以是整数、浮点数、字符串、元组、列表、字典。
C语言中一个典型的swicht-case语句像下面这样,在switch里包含要判断的变量x,case语句后则是匹配变量值是多少,如果满足这个匹配条件,就执行“case n:”后面的语句,直到遇到break退出swith语句。
#include <stdio.h>
int main() {
int x;
printf("输入数值: ");
scanf("%d", &x);
switch(x) {
case 1:
printf("星期一\n");
break;
case 2:
printf("星期二\n");
break;
case 3:
printf("星期三\n");
break;
case 4:
printf("星期四\n");
break;
case 5:
printf("星期五\n");
break;
case 6:
printf("星期六\n");
break;
case 7:
printf("星期天\n");
break;
default:
printf("输入错误\n");
break;
}
return 0;
}
输出结果:
4 星期一
在Python3.10里面类似的功能可以用match-case语句实现:
x = int(input("输入数值: "))
match x:
case 1:print('星期一')
case 2:print('星期二')
case 3:print('星期三')
case 4:print('星期四')
case 5:print('星期五')
case 6:print('星期六')
case 7:
print('星期天')
case _:
print("输入错误")
输出结果:
输入数值: 1 #这里是每次输入只能输出一个结果,为了排版写在了一起
星期一
输入数值: 7
星期天
输入数值: 10
输入错误
match类似C语言的switch关键字,后面跟要匹配的变量;case跟各种不同的条件,其后面是满足某一条件要执行的语句;每个case语句结束时不需要break语句。
最后一个case加下划线表示缺省匹配,如果前面的条件没有匹配上就跑到这个case里面执行,类似于C语言的default,缺省匹配不可以放置在其他case语句前,否则会报SyntaxError错误: wildcard makes remaining patterns unreachable。当然缺省匹配并不是必须的,加一个缺省匹配可以让程序运行的结果更有可读性。
二、match-case的基本用法
1、可匹配的数据类型
1)匹配对象类型为字符串类型
不像C语言里面switch所匹配的变量类型只能是整数型或者字符型,Python里的匹配对象类型可以用字符串类型:
x = input("输入英文简写: ")
match x:
case 'mon':print('星期一')
case 'tue':print('星期二')
case 'wed':print('星期三')
case 'thur':print('星期四')
case 'fri':print('星期五')
case 'sat':print('星期六')
case 'sun':print('星期天')
case _:print("输入错误")
输出结果:
输入英文简写: sun #这里是每次输入只能输出一个结果,为了排版写在了一起
星期天
输入英文简写: none
输入错误
2)匹配对象类型为浮点型
如果一定要用浮点型来做匹配那也是可以的,下面这个例子中要匹配的变量x为整型,case后的值为整型或浮点型:
x = int(input("输入数值: "))
match x:
case 1:print('星期一')
case 2:print('星期二')
case 3.0:print('星期三')
case 4.0:print('星期四')
case 5.0:print('星期五')
case 6.0:print('星期六')
case 7.0:print('星期天')
case _:print("输入错误")
输出结果:
输入数值: 1 #这里是每次输入只能输出一个结果,为了排版写在了一起
星期一
输入数值: 3
星期三
输入数值: 9
输入错误
还可以这样,要匹配的变量x为浮点型,case后的值为整数型或浮点型:
x = float(input("输入数值: "))
match x:
case 1:print('星期一')
case 2:print('星期二')
case 3:print('星期三')
case 4:print('星期四')
case 5.5:print('星期五')
case 6:print('星期六')
case 7.0:print('星期天')
case _:print("输入错误")
输出结果:
输入数值: 1 #这里是每次输入只能输出一个结果,为了排版写在了一起
星期一
输入数值: 1.0
星期一
输入数值: 5 #要匹配的变量为5.5才是星期五,这里的5匹配到了缺省匹配,所以是输入错误
输入错误
输入数值: 5.5
星期五
输入数值: 7.2
输入错误
从上面的例子可以看出些端倪,match后的变量类型和case后的类型并不一定要相同。
3)概括:匹配类型为可以是整数、浮点数、字符串、元组、列表、字典
下面设计的这个实验就是通过输入不同的数值模拟函数返回不同的数据类型,让match后的变量类型都不一样,在case里如果有一种能匹配上就输出相应的打印:
def func():
x = int(input("输入数值: "))
if x==1:return 1.0
elif x==2:return '2'
elif x==3:return (3,0,1)
elif x==4:return [4,0,0]
elif x==5:return {'5':'k','A':1}
elif x==6:return 6
elif x==7:return set((7,))
else:return x
x=func()
print(type(x))
match x:
case 1.0:print('星期一')
case '2':print('星期二')
case (3,0,1):print('星期三')
case [4,0,0]:print('星期四')
case {'5':'k','A':1}:print('星期五')
case 6:print('星期六')
case set((7,)):print('星期天')
输出结果:
输入数值: 0 #这里是每次输入只能输出一个结果,为了排版写在了一起
<class 'int'>
输入错误
输入数值: 1
<class 'float'>
星期一
输入数值: 2
<class 'str'>
星期二
输入数值: 3
<class 'tuple'>
星期三
输入数值: 4
<class 'list'>
星期四
输入数值: 5
<class 'dict'>
星期五
输入数值: 6
<class 'int'>
星期六
输入数值: 7
<class 'set'>
输入错误
从上面的例子可以看到,Python里的match-case数据类型(对象类型)丰富多彩,可以是整数、浮点数、字符串、元组、列表、字典,但是对于set类型即使看起来值是一样的,却没有匹配成功。
2、多条件匹配
我们知道在C语言里面如果要匹配多条件,可以将case语句并列书写且其后面不带break语句,比如下面这个例子输入15匹配工作日,输入67匹配周末:我们知道在C语言里面如果要匹配多条件,可以将case语句并列书写且其后面不带break语句,比如下面这个例子输入1~ 5匹配工作日,输入6~ 7匹配周末:
switch(x){
case 1:
case 2:
case 3:
case 4:
case 5: printf("工作日\n"); break;
case 6:
case 7: printf("周末\n"); break;
default:printf("输入错误\n"); break;
}
当x为1,2,3,4,5中任何一个时都能匹配上printf(“工作日\n”),从而实现多条件的匹配。
我们来看下Python里是不是也可以这么实现多条件的匹配:
x = int(input("输入数值: "))
match x:
case 1:
case 2:
case 3:
case 4:
case 5:print('工作日')
case 6:
case 7:print('周末')
case _:print("输入错误")
输出结果:
File "D:\pythonCode\main.py", line 5
case 2:
^
IndentationError: expected an indented block after 'case' statement on line 4
Process finished with exit code 1
不好意思,提示IndentationError错误啦,在Python里是不可以这么写的!
Python的match-case语句要用逻辑或符号(|)表示多条件的匹配,case condition1 | condition2 | condition3 |……:
x = int(input("输入数值: "))
match x:
case 1 | 2 | 3 | 4 | 5:
print('工作日')
case 6 | 7:
print('周末')
case _:
print("输入错误")
输出结果:
输入数值: 1 #这里是每次输入只能输出一个结果,为了排版写在了一起
工作日
输入数值: 5
工作日
输入数值: 6
周末
输入数值: 7
周末
输入数值: 8
输入错误
注意不要使用or代替逻辑或符号,否则会提示SyntaxError错误:
File "D:\pythonCode\main.py", line 3
case 1 or 2 or 3 or 4 or 5:
^^
SyntaxError: invalid syntax
Process finished with exit code 1
3、通配符匹配
1)匹配对象为单星号通配符
match-case语句还支持通配符匹配,可以使用类似于match x:case [cond1,cond2,.……,*rem]的通配符匹配,只要列表或者元组的前几个元素的值和顺序满足cond1,cond2,.……,,剩余的元素不管有多少个,都能达到匹配条件,并且rem表示剩余的元素组成的列表。这里的条件不一定像cond1,cond2,……这样有多个,也可以只有一个cond1。下面这个例子输入不同的值返回不同长度的列表,匹配条件为[1,*rem]只要被匹配对象第0个元素为1就能匹配上:
def func():
x = int(input("输入数值: "))
if x==0: return [0,1]
elif x==1: return [1]
elif x==2: return [1,2]
elif x==3: return [1,2,3]
else: return None
x=func()
print('x:',x)
match x:
case [1,*rem]:
print('rem:',rem)
case _:
print("未匹配")
输出结果:
输入数值: 0 #这里是每次输入只能输出一个结果,为了排版写在了一起
x: [0, 1]
未匹配 ###### x的第0个元素为0,不符合匹配条件中第0个元素为1的要求
输入数值: 1
x: [1]
rem: [] ###### x的第0个元素为1,满足匹配条件,因为只有1个元素,所以rem为空
输入数值: 2
x: [1, 2]
rem: [2] ###### x的第0个元素为1,满足匹配条件,rem为剩余的元素组成的列表
输入数值: 3
x: [1, 2, 3]
rem: [2, 3]
输入数值: 5
x: None
未匹配 ###### x值为None,不能匹配
tuple也可以用通配符匹配,我们将上面的例子x改成tuple类型,case匹配对象也是tuple类型,其他的条件不变,可以看到匹配的方式和list类型是一样的,但是需要注意的是如果能匹配上,rem得到的仍然是一个list类型而不是tuple类型:
def func():
x = int(input("输入数值: "))
if x==0: return (0,1)
elif x==1: return (1,)
elif x==2: return (1,2)
elif x==3: return (1,2,3)
else: return None
x=func()
print('x:',x)
match x:
case (1,*rem):
print(type(rem),'rem:',rem)
case _:
print("未匹配")
输出结果:
输入数值: 3 #这里是每次输入只能输出一个结果,为了排版写在了一起
x: (1, 2, 3)
<class 'list'> rem: [2, 3] ###虽然匹配对象为tuple,rem得到的仍然是list
输入数值: 1
x: (1,)
<class 'list'> rem: []
2)匹配对象为双星通配符
双星号通配符可以用于字典的部分键-值匹配,比如下面这个例子中,case匹配的对象只要有一对键-值为 {2: “星期二”} 就能匹配上,并且可以得到rem的值为剩余的键-值。
def func():
x = int(input("输入数值: "))
if x==0: return {1: "星期一"}
elif x==1: return {2: "星期二"}
elif x==2: return {1: "星期一", 2: "星期二"}
elif x==3: return {1: "星期一", 2: "星期二",3:'星期三'}
else: return None
x=func()
print('x:',x)
match x:
case {2: "星期二", **rem}:
print('rem:',rem)
case _:
print('未匹配')
输出结果:
输入数值: 0 #这里是每次输入只能输出一个结果,为了排版写在了一起
x: {1: '星期一'}
未匹配 ######没有包含{2: "星期二"},所以没有匹配上
输入数值: 1
x: {2: '星期二'}
rem: {} #####能匹配上,且rem为一个空字典{}
输入数值: 2
x: {1: '星期一', 2: '星期二'}
rem: {1: '星期一'} ##### 去除其中的键-值{2: "星期二"}剩余的键-值{1: '星期一'}赋给了rem
输入数值: 3
x: {1: '星期一', 2: '星期二', 3: '星期三'}
rem: {1: '星期一', 3: '星期三'}
输入数值: 10
x: None
未匹配 ##### x值为None,不能匹配