优秀的编程知识分享平台

网站首页 > 技术文章 正文

如何在 Python 中使用匹配语句(python匹配函数)

nanyue 2024-07-20 23:46:23 技术文章 15 ℃

Python 3.10 最大的引入是 Match-Case 语句。 这是 Java switch 语句的 Python 等价物,是许多程序员长期以来一直在寻求的东西。

但是现在这个伟大的命令已经被引入,学习如何充分利用它是很重要的。 这是有关 match-case 语句如何工作的快速指南。


基础

首先,让我们看一个基本的例子。 假设我们有一个将颜色表示为字符串的变量。 它可以是 "green" 、 "red" 、 "yellow" 和 "blue" 。 在 Python 3.9 中,您将使用具有四个分支的 if 语句。

但是,现在我们可以使用 match 语句。 这将使您的代码更易于阅读和维护。 这是执行此操作的代码:

color = "yellow"match color:
  case "red":
    print("The color is red")
  case "yellow":
    print("Wow, you picked yellow")
  case "green":
    print("We are using a  green color")
  case "blue":
    print("Blue like the sea...")

我们首先在 match 关键字之后定义我们要匹配的变量。 然后,每个案例都以 case 关键字开头,然后是我们要检查的模式。 match-case 语句将只运行匹配的第一个 case 下的代码。

因此,在本例中,匹配语句将打印“哇,你选了黄色”。 现在考虑另一种情况:

match color:
  case "yellow":
    print("Wow, you picked yellow")
  case "blue":
    print("Blue like the sea...")
  case "yellow":
    print("Yellow again!")

在这种情况下,永远不会执行匹配“黄色”的第二种情况,因为变量将进入第一种情况,然后跳到语句的末尾(很像 if ... elifcase)。


组合模式

现在假设我们要为黄色和紫色执行相同的代码。 对于两种不同的情况,两次编写相同的代码是不好的做法。

相反,我们可以使用 | 运算符在同一案例中包含多个模式:

match color:
  case "yellow" | "purple":
    print("Wow, you picked yellow or purple")
  case "blue":
    print("Blue like the sea...")
  case "red":
    print("Red here!")

如果颜色是指定的两种颜色之一,则此处将执行第一种情况。


包罗万象的案例

最后,如果变量与任何先前的案例都不匹配,您可能希望有一个将始终执行的案例。 您可以通过以下方式获得:

color = "purple"match color:
  case "yellow":
    print("Wow, you picked yellow")
  case "blue":
    print("Blue like the sea...")
  case other_color:
    print("You chose a different color:", other_color)

在最后一个 case 分支中,other_color 是一个匹配所有内容的变量。 所以在这种情况下,由于没有其他情况与我们的颜色匹配,那么 other_color 将采用与颜色相同的值,我们将执行此代码。

将这个包罗万象的案例放在最后一个很重要:事实上,它总是匹配任何输入,因此它之后的案例永远不会被执行。


匹配列表

现在我们了解了基础知识,让我们看看 Match 语句的一个强大功能:序列上的模式匹配。

我们可以做的最简单的事情是匹配特定元素:

my_list = [1, 2, 3]match my_list:
  case [1, 2, 3]:
    print("contains 1, 2, 3")
  case [4, 5]:
    print("Contains 4 and 5")
  case _:
    print("No match")

这里 my_list 将执行第一种情况下的代码,因为元素是相同的。 请注意,我们还在最后添加了一个包罗万象的案例。

但是,我们可以做的还有很多! 首先,我们可以将一些元素匹配到精确值,而将其他元素留给变量:

my_list = [1, 2, 4]match my_list:
  case [1, 2]:
    print("contains only 1 and 2")
  case [1, 2, el]:
    print("Last element is", el)
  case _:
    print("No match")

看第二种情况:如果列表包含三个元素,这将被执行。 前两个必须是 1 和 2,而最后一个可以是任何值。 变量 el 将获取最后一个元素的值,我们可以在 case 中将其用作普通变量。

此外,我们可以将列表拆分为头部(第一个元素)和尾部(包含除头部之外的所有元素的列表):

match l:
  case [head, *tail]:
    print("First is", head)
    print("Rest is", tail)
  case []: 
    print("Empty")

如果我们想创建一个递归函数,它在头部做某事,然后在列表的其余部分上递归,这特别有用。 例如:

def recursive_sum(my_list):
  """Calculate the sum of the elements with pattern matching"""
  match my_list:
    case []:
      return 0
    case [head, *tail]:
      return head + recursive_sum(tail)

这里我们递归地计算列表的总和:如果列表为空,总和将为零。 否则,总和是头部的值加上列表其余部分的递归总和。


有条件的情况

现在让我们看看如何使用 if 语句来“停用”某些情况。

例如,假设我们有一个整数 n ,并且我们想要执行模式匹配。 我们有三种情况:一种情况是 nis 为零,一种情况是 n<100,最后一种情况是所有其他情况。 为单个案例编写 99 个值是不切实际的,但幸运的是 Python 具有我们需要的功能:我们可以在案例中添加 if 语句。

下面是我们将如何创建我们的匹配:

num = 5match num:
  case 0:
    print("It is zero")
  case n if n<100:
    print(n, "less than 100 but bigger than zero")
  case _:
    print("A really big number")

如果没有 if 语句,第二种情况将是一个包罗万象的情况,所以第三种情况永远不会被执行。 但是,通过添加 if,仅当 n<100 时才使用第二种情况。 否则,代码将表现得好像这种情况不匹配。


结构模式匹配

最后,我们将看到如何在 match 语句中使用自定义类。

例如,考虑这个类:

class ButtonClicked:
  def __init__(self, mouse_button: str, x: int, y: int):
    self.x = x
    self.y = y
    self.mouse_button = mouse_button

该类表示鼠标在屏幕上的点击。 它存储 x 和 y 坐标,以及一个可以是 "left" 或 "right" 的字符串,具体取决于按下鼠标的哪个按钮。

现在我们想要两种不同的情况,一种用于左侧按钮,另一种用于右侧按钮。 这可以通过以下方式实现:

b = ButtonClicked("left", 3, 5)match b:
  case ButtonClicked(mouse_button="left"):
    print("Left mouse clicked at", b.x, b.y)
  case ButtonClicked(mouse_button="right"):
    print("Right mouse clicked at", b.x, b.y)

在每种情况下,我们都指定变量 mouse_clicked 应采用哪个值。


结论

感谢您阅读本教程,希望对您有所帮助!

最近发表
标签列表