Python 中的結(jié)構(gòu)模式匹配及重要性
在 Python 3.10 之前,我們沒有任何內(nèi)置的方式來使用結(jié)構(gòu)模式匹配,在其他編程語言中稱為 switch-case。 從 Python 3.10 版本開始,我們不能使用 match ... case 語句來模擬 switch ... case 語句。
本篇文章介紹結(jié)構(gòu)模式匹配及其在 Python 中的重要性。 它還使用不同的模式來演示如何使用 match … case 語句。
結(jié)構(gòu)模式匹配簡介及其重要性
截至 2021 年初,我們無法在低于或等于 3.9 的已發(fā)布 Python 版本中使用 match 關(guān)鍵字。 那時,我們習(xí)慣于使用字典或嵌套的 if/elif/else 語句來模擬 switch ... case。
但是,Python 3.10 引入了一個新特性,稱為結(jié)構(gòu)模式匹配(match ... case 語句)。 它相當于我們在 Java、C++ 和許多其他編程語言中使用的 switch ... case 語句。
這一新功能使我們能夠編寫簡單、易于閱讀且最不容易出錯的流程控制語句。
在 Python 中使用結(jié)構(gòu)模式匹配
結(jié)構(gòu)模式匹配用作 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 關(guān)鍵字,它將顏色變量的值與各種指定的案例進行匹配,其中每個案例都以 case 關(guān)鍵字開頭,后跟我們要比較或檢查的模式。
模式可以是以下之一:
- 文本模式
- 捕獲模式
- 通配符模式
- 定值模式
- 序列模式
- 映射模式
- 類模式
- 或模式
- 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 來檢測和解構(gòu)數(shù)據(jù)結(jié)構(gòu)
示例代碼:
student = {
"name": {"first": "Mehvish", "last": "Ashiq"},
"section": "B"
}
match student:
case {"name": {"first": firstname}}:
print(firstname)輸出:
Mehvish
在上面的示例中,結(jié)構(gòu)模式匹配在以下兩行代碼中起作用:
match student:
case {"name": {"first": firstname}}:我們使用 match … case 語句通過從學(xué)生數(shù)據(jù)結(jié)構(gòu)中提取學(xué)生的名字來找到它。 在這里,student 是一個包含學(xué)生信息的字典。
案例行指定我們的模式來匹配學(xué)生。 考慮到上面的例子,我們尋找一個帶有“name”鍵的字典,其值為一個新字典。
這個嵌套字典包含一個“first”鍵,其值綁定到 firstname 變量。 最后,我們使用 firstname 變量來打印值。
如果您更深入地觀察它,我們已經(jīng)了解了這里的映射模式。 如何? 映射模式看起來像 {"student": s, "emails": [*es]},它匹配映射與至少一組指定的鍵。
如果所有子模式都匹配它們對應(yīng)的值,那么它將在與鍵對應(yīng)的值匹配期間綁定任何子模式綁定。 如果我們想要允許捕獲額外的項目,我們可以在模式的末尾添加 **rest。
使用 match … case 與捕獲模式和序列模式
示例代碼:
def sum_list_of_numbers(numbers):
match numbers:
case []:
return 0
case [first, *rest]:
return first + sum_list_of_numbers(rest)
sum_list_of_numbers([1,2,3,4])輸出:
10
這里,我們使用遞歸函數(shù),使用捕獲模式捕獲到指定模式的匹配,并綁定到名字上。
在此代碼示例中,如果第一種情況與空列表匹配,則第一種情況返回 0 作為總和。 第二種情況使用帶有兩個捕獲模式的序列模式來匹配列表與多個項目/元素之一。
在這里,列表中的第一項被捕獲并綁定到名字,而第二個捕獲模式 *rest 使用解包語法來匹配任意數(shù)量的項目/元素。
%> 請注意 ,其余部分綁定到包含數(shù)字的所有項目/元素的列表,不包括第一個。 為了獲得輸出,我們通過傳遞上面給出的數(shù)字列表來調(diào)用 sum_list_of_numbers() 函數(shù)。
使用 match … case 和通配符模式
示例代碼:
def sum_list_of_numbers(numbers):
match numbers:
case []:
return 0
case [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'
我們在學(xué)習(xí) match ... case 語句的基本用法時學(xué)習(xí)了使用通配符模式的概念,但沒有在那里介紹通配符模式術(shù)語。 想象一下前兩種情況不匹配的情況,我們需要一個 catchall 模式作為我們的最終情況。
例如,如果我們得到任何其他類型的數(shù)據(jù)結(jié)構(gòu)而不是列表,我們希望引發(fā)錯誤。 在這里,我們可以使用 _ 作為通配符模式,它將匹配任何內(nèi)容而不綁定到名稱。 我們在最后一個案例中添加錯誤處理以通知用戶。
你怎么說? 我們的模式適合搭配嗎? 讓我們通過傳遞字符串值列表來調(diào)用 sum_list_of_numbers() 函數(shù)來測試它,如下所示:
sum_list_of_numbers(['1','2','3','4'])
它將產(chǎn)生以下錯誤:
TypeError: can only concatenate str (not "int") to str
因此,我們可以說該模式仍然不夠萬無一失。 為什么? 因為我們將列表類型數(shù)據(jù)結(jié)構(gòu)傳遞給 sum_list_of_numbers() 函數(shù),但具有字符串類型值,而不是我們預(yù)期的 int 類型。
請參閱以下部分以了解如何解決它。
在類模式中使用 match … case
示例代碼:
def sum_list_of_numbers(numbers):
match numbers:
case []:
return 0
case [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; 因此,求和僅適用于我們可以用數(shù)字相加的類型。 請注意,Python 不知道如何添加文本字符串和數(shù)字。
所以,我們可以使用類模式來限制我們的模式只匹配整數(shù)。 類模式類似于映射模式,但匹配屬性而不是鍵。
使用 match … case 和 OR 模式
示例代碼:
def sum_list_of_numbers(numbers):
match numbers:
case []:
return 0
case [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")假設(shè)我們想讓 sum_list_of_numbers() 函數(shù)用于值列表,無論是 int 類型還是 float 類型的值。 我們使用用豎線符號 (|) 表示的 OR 模式。
如果指定列表包含 int 或 float 類型值以外的值,則上述代碼必須引發(fā) 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:傳遞具有除 int 和 float 類型之外的任何其他類型的列表:
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() 函數(shù)適用于 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!
此示例使用與文字對象匹配的文字模式,例如,顯式數(shù)字或字符串,正如我們在學(xué)習(xí) match ... case 語句的基本用法時所做的那樣。
它是最基本的模式類型,讓我們模擬一個類似于 Java、C++ 和其他編程語言的 switch ... case 語句。 您可以訪問此頁面以了解所有模式。
到此這篇關(guān)于Python 中的結(jié)構(gòu)模式匹配的文章就介紹到這了,更多相關(guān)Python結(jié)構(gòu)模式匹配內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
通過celery異步處理一個查詢?nèi)蝿?wù)的完整代碼
今天小編就為大家分享一篇通過celery異步處理一個查詢?nèi)蝿?wù)的完整代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11
Python實現(xiàn)將.py代碼轉(zhuǎn)換為帶語法高亮的Word和PDF
本指南介紹了幾種將?Python?代碼轉(zhuǎn)換為?Word?和?PDF?文檔的方法,確保您的代碼易于閱讀,并且以專業(yè)的方式呈現(xiàn),有需要的小伙伴可以參考下2025-12-12
使用spyder3調(diào)試python程序的實現(xiàn)步驟
本文主要介紹了使用spyder3調(diào)試python程序的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12
Python使用Matplotlib進行圖案填充和邊緣顏色分離的三種方法
Matplotlib是Python中功能強大的繪圖庫,允許廣泛的自定義選項,一個常見的要求是分離出圖中的圖案填充和邊緣顏色,默認情況下,Matplotlib中的填充顏色與邊緣顏色相關(guān)聯(lián),但有一些方法可以獨立自定義這些顏色,本文將深入研究如何實現(xiàn)這一點的技術(shù)細節(jié),并提供分步說明和示例2025-01-01

