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)鍵字。 那時(shí),我們習(xí)慣于使用字典或嵌套的 if/elif/else 語句來模擬 switch ... case。
但是,Python 3.10 引入了一個(gè)新特性,稱為結(jié)構(gòu)模式匹配(match ... case 語句)。 它相當(dāng)于我們在 Java、C++ 和許多其他編程語言中使用的 switch ... case 語句。
這一新功能使我們能夠編寫簡單、易于閱讀且最不容易出錯(cuò)的流程控制語句。
在 Python 中使用結(jié)構(gòu)模式匹配
結(jié)構(gòu)模式匹配用作 switch … case 語句,比這更強(qiáng)大。 如何? 讓我們探索下面的一些示例,以了解它們在不同情況下的用途。
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...
在這里,我們首先有一個(gè)包含藍(lán)色的可變顏色。 然后,我們使用 match 關(guān)鍵字,它將顏色變量的值與各種指定的案例進(jìn)行匹配,其中每個(gè)案例都以 case 關(guān)鍵字開頭,后跟我們要比較或檢查的模式。
模式可以是以下之一:
- 文本模式
- 捕獲模式
- 通配符模式
- 定值模式
- 序列模式
- 映射模式
- 類模式
- 或模式
- walrus 模式
match ... case 語句只運(yùn)行第一個(gè)匹配的 case 下的代碼。
如果沒有匹配到 case 怎么辦? 用戶將如何知道它? 為此,我們可以有一個(gè)默認(rèn)情況,如下所示。
示例代碼:
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 是一個(gè)包含學(xué)生信息的字典。
案例行指定我們的模式來匹配學(xué)生。 考慮到上面的例子,我們尋找一個(gè)帶有“name”鍵的字典,其值為一個(gè)新字典。
這個(gè)嵌套字典包含一個(gè)“first”鍵,其值綁定到 firstname 變量。 最后,我們使用 firstname 變量來打印值。
如果您更深入地觀察它,我們已經(jīng)了解了這里的映射模式。 如何? 映射模式看起來像 {"student": s, "emails": [*es]},它匹配映射與至少一組指定的鍵。
如果所有子模式都匹配它們對應(yīng)的值,那么它將在與鍵對應(yīng)的值匹配期間綁定任何子模式綁定。 如果我們想要允許捕獲額外的項(xià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 作為總和。 第二種情況使用帶有兩個(gè)捕獲模式的序列模式來匹配列表與多個(gè)項(xiàng)目/元素之一。
在這里,列表中的第一項(xiàng)被捕獲并綁定到名字,而第二個(gè)捕獲模式 *rest 使用解包語法來匹配任意數(shù)量的項(xiàng)目/元素。
%> 請注意 ,其余部分綁定到包含數(shù)字的所有項(xiàng)目/元素的列表,不包括第一個(gè)。 為了獲得輸出,我們通過傳遞上面給出的數(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 語句的基本用法時(shí)學(xué)習(xí)了使用通配符模式的概念,但沒有在那里介紹通配符模式術(shù)語。 想象一下前兩種情況不匹配的情況,我們需要一個(gè) catchall 模式作為我們的最終情況。
例如,如果我們得到任何其他類型的數(shù)據(jù)結(jié)構(gòu)而不是列表,我們希望引發(fā)錯(cuò)誤。 在這里,我們可以使用 _ 作為通配符模式,它將匹配任何內(nèi)容而不綁定到名稱。 我們在最后一個(gè)案例中添加錯(cuò)誤處理以通知用戶。
你怎么說? 我們的模式適合搭配嗎? 讓我們通過傳遞字符串值列表來調(diào)用 sum_list_of_numbers() 函數(shù)來測試它,如下所示:
sum_list_of_numbers(['1','2','3','4'])
它將產(chǎn)生以下錯(cuò)誤:
TypeError: can only concatenate str (not "int") to str
因此,我們可以說該模式仍然不夠萬無一失。 為什么? 因?yàn)槲覀儗⒘斜眍愋蛿?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。 讓我們考慮以下所有三種情況進(jìn)行測試。
測試 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 語句的基本用法時(shí)所做的那樣。
它是最基本的模式類型,讓我們模擬一個(gè)類似于 Java、C++ 和其他編程語言的 switch ... case 語句。 您可以訪問此頁面以了解所有模式。
到此這篇關(guān)于Python 中的結(jié)構(gòu)模式匹配的文章就介紹到這了,更多相關(guān)Python結(jié)構(gòu)模式匹配內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python區(qū)塊鏈實(shí)現(xiàn)簡版工作量證明
這篇文章主要為大家介紹了python區(qū)塊鏈實(shí)現(xiàn)簡版工作量證明詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
Python實(shí)現(xiàn)的json文件讀取及中文亂碼顯示問題解決方法
這篇文章主要介紹了Python實(shí)現(xiàn)的json文件讀取及中文亂碼顯示問題解決方法,涉及Python針對json文件的讀取載入、編碼轉(zhuǎn)換等相關(guān)操作技巧,需要的朋友可以參考下2018-08-08
剖析Python的Tornado框架中session支持的實(shí)現(xiàn)代碼
這篇文章主要介紹了剖析Python的Tornado框架中session支持的實(shí)現(xiàn)代碼,這樣就可以使用Django等框架中大家所熟悉的session了,需要的朋友可以參考下2015-08-08
Python?Django教程之實(shí)現(xiàn)新聞應(yīng)用程序
Django是一個(gè)用Python編寫的高級框架,它允許我們創(chuàng)建服務(wù)器端Web應(yīng)用程序。在本文中,我們將了解如何使用Django創(chuàng)建新聞應(yīng)用程序,感興趣的可以嘗試一下2022-10-10
Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)在字典中將鍵映射到多個(gè)值上的方法
這篇文章主要介紹了Python在字典中將鍵映射到多個(gè)值上的方法,涉及Python針對字典的相關(guān)映射與初始化相關(guān)操作技巧,需要的朋友可以參考下2018-02-02
Python 實(shí)現(xiàn)鍵盤鼠標(biāo)按鍵模擬
這篇文章主要介紹了Python 實(shí)現(xiàn)鍵盤按鍵模擬的方法,幫助大家提高辦公效率,感興趣的朋友可以了解下2020-11-11
詳解Python中的函數(shù)參數(shù)傳遞方法*args與**kwargs
本文將討論P(yáng)ython的函數(shù)參數(shù)。我們將了解args和kwargs,/和的都是什么,雖然這個(gè)問題是一個(gè)基本的python問題,但是在我們寫代碼時(shí)會(huì)經(jīng)常遇到,比如timm中就大量使用了這樣的參數(shù)傳遞方式2023-03-03
Keras 利用sklearn的ROC-AUC建立評價(jià)函數(shù)詳解
這篇文章主要介紹了Keras 利用sklearn的ROC-AUC建立評價(jià)函數(shù)詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06

