Python 中的結(jié)構(gòu)模式匹配及重要性
在 Python 3.10 之前,我們沒有任何內(nèi)置的方式來使用結(jié)構(gòu)模式匹配,在其他編程語(yǔ)言中稱為 switch-case。 從 Python 3.10 版本開始,我們不能使用 match ... case
語(yǔ)句來模擬 switch ... case
語(yǔ)句。
本篇文章介紹結(jié)構(gòu)模式匹配及其在 Python 中的重要性。 它還使用不同的模式來演示如何使用 match … case 語(yǔ)句。
結(jié)構(gòu)模式匹配簡(jiǎn)介及其重要性
截至 2021 年初,我們無法在低于或等于 3.9 的已發(fā)布 Python 版本中使用 match 關(guān)鍵字。 那時(shí),我們習(xí)慣于使用字典或嵌套的 if/elif/else 語(yǔ)句來模擬 switch ... case
。
但是,Python 3.10 引入了一個(gè)新特性,稱為結(jié)構(gòu)模式匹配(match ... case
語(yǔ)句)。 它相當(dāng)于我們?cè)?Java、C++ 和許多其他編程語(yǔ)言中使用的 switch ... case
語(yǔ)句。
這一新功能使我們能夠編寫簡(jiǎn)單、易于閱讀且最不容易出錯(cuò)的流程控制語(yǔ)句。
在 Python 中使用結(jié)構(gòu)模式匹配
結(jié)構(gòu)模式匹配用作 switch … case 語(yǔ)句,比這更強(qiáng)大。 如何? 讓我們探索下面的一些示例,以了解它們?cè)诓煌闆r下的用途。
match … case 語(yǔ)句的基本使用
示例代碼:
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ǔ)句只運(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 來檢測(cè)和解構(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 語(yǔ)句通過從學(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]}
,它匹配映射與至少一組指定的鍵。
如果所有子模式都匹配它們對(duì)應(yīng)的值,那么它將在與鍵對(duì)應(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
使用解包語(yǔ)法來匹配任意數(shù)量的項(xiàng)目/元素。
%> 請(qǐ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'
我們?cè)趯W(xué)習(xí) match ... case
語(yǔ)句的基本用法時(shí)學(xué)習(xí)了使用通配符模式的概念,但沒有在那里介紹通配符模式術(shù)語(yǔ)。 想象一下前兩種情況不匹配的情況,我們需要一個(gè) catchall 模式作為我們的最終情況。
例如,如果我們得到任何其他類型的數(shù)據(jù)結(jié)構(gòu)而不是列表,我們希望引發(fā)錯(cuò)誤。 在這里,我們可以使用 _ 作為通配符模式,它將匹配任何內(nèi)容而不綁定到名稱。 我們?cè)谧詈笠粋€(gè)案例中添加錯(cuò)誤處理以通知用戶。
你怎么說? 我們的模式適合搭配嗎? 讓我們通過傳遞字符串值列表來調(diào)用 sum_list_of_numbers() 函數(shù)來測(cè)試它,如下所示:
sum_list_of_numbers(['1','2','3','4'])
它將產(chǎn)生以下錯(cuò)誤:
TypeError: can only concatenate str (not "int") to str
因此,我們可以說該模式仍然不夠萬(wàn)無一失。 為什么? 因?yàn)槲覀儗⒘斜眍愋蛿?shù)據(jù)結(jié)構(gòu)傳遞給 sum_list_of_numbers() 函數(shù),但具有字符串類型值,而不是我們預(yù)期的 int 類型。
請(qǐng)參閱以下部分以了解如何解決它。
在類模式中使用 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ù)字相加的類型。 請(qǐng)注意,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 類型的值。 我們使用用豎線符號(hào) (|) 表示的 OR 模式。
如果指定列表包含 int 或 float 類型值以外的值,則上述代碼必須引發(fā) ValueError。 讓我們考慮以下所有三種情況進(jìn)行測(cè)試。
測(cè)試 1:傳遞具有 int 類型值的列表:
sum_list_of_numbers([1,2,3,4]) #output is 10
測(cè)試 2:傳遞具有 float 類型值的列表:
sum_list_of_numbers([1.0,2.0,3.0,4.0]) #output is 10.0
測(cè)試 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!
此示例使用與文字對(duì)象匹配的文字模式,例如,顯式數(shù)字或字符串,正如我們?cè)趯W(xué)習(xí) match ... case
語(yǔ)句的基本用法時(shí)所做的那樣。
它是最基本的模式類型,讓我們模擬一個(gè)類似于 Java、C++ 和其他編程語(yǔ)言的 switch ... case
語(yǔ)句。 您可以訪問此頁(yè)面以了解所有模式。
到此這篇關(guān)于Python 中的結(jié)構(gòu)模式匹配的文章就介紹到這了,更多相關(guān)Python結(jié)構(gòu)模式匹配內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python區(qū)塊鏈實(shí)現(xiàn)簡(jiǎn)版工作量證明
這篇文章主要為大家介紹了python區(qū)塊鏈實(shí)現(xiàn)簡(jiǎn)版工作量證明詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Python實(shí)現(xiàn)的json文件讀取及中文亂碼顯示問題解決方法
這篇文章主要介紹了Python實(shí)現(xiàn)的json文件讀取及中文亂碼顯示問題解決方法,涉及Python針對(duì)json文件的讀取載入、編碼轉(zhuǎn)換等相關(guān)操作技巧,需要的朋友可以參考下2018-08-08剖析Python的Tornado框架中session支持的實(shí)現(xiàn)代碼
這篇文章主要介紹了剖析Python的Tornado框架中session支持的實(shí)現(xiàn)代碼,這樣就可以使用Django等框架中大家所熟悉的session了,需要的朋友可以參考下2015-08-08Python?Django教程之實(shí)現(xiàn)新聞應(yīng)用程序
Django是一個(gè)用Python編寫的高級(jí)框架,它允許我們創(chuàng)建服務(wù)器端Web應(yīng)用程序。在本文中,我們將了解如何使用Django創(chuàng)建新聞應(yīng)用程序,感興趣的可以嘗試一下2022-10-10Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)在字典中將鍵映射到多個(gè)值上的方法
這篇文章主要介紹了Python在字典中將鍵映射到多個(gè)值上的方法,涉及Python針對(duì)字典的相關(guān)映射與初始化相關(guān)操作技巧,需要的朋友可以參考下2018-02-02Python 實(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-03Keras 利用sklearn的ROC-AUC建立評(píng)價(jià)函數(shù)詳解
這篇文章主要介紹了Keras 利用sklearn的ROC-AUC建立評(píng)價(jià)函數(shù)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-06-06