Web制作、Web開発の歩き方

初心者のためのDjango入門

■第23話:Pythonのmatch文

(最終更新日:2024.11.04)

Djangoフレームワークのイメージ
この記事は5分で読めます!
(絵が小さい場合はスマホを横に)

「match文で条件判定を簡単に!」

Python3.10になって、新たな機能としてmatch文が使えるようになった。 matchはswitchと似たような構文である。 switchは、C言語やJavaScriptで使われるメジャーな構文であるが、Pythonでは近年matchを採用した。 今回は、他の言語でよく使われるswitch文との違いを踏まえて、Pythonのmatch文について解説する。


1.switch文との違い

Python自体にはswitch文は無いので、ここではJavaScriptのswitch文と比較する。 JavaScriptのswitch文は、ある変数や式の値に基づいて分岐し、case句の中では文字列や定数のみをサポートする。 つまり、文字列や数値の一致を連続的に判定するのが一般的なswitch文になる。

下記では、valueの値がAかB、その他であるかを判定できる。判定したら、consoleにその結果を表示する。 breakを書くことで、当てはまったcase以降のcase判定を飛ばし、switch文を抜けることができる。

JavaScriptのswitch文

JavaScriptのswitch文

Pythonのmatch文は幾つか違いがある。パターンマッチングとして、文字列や定数に加え、シーケンス、データ構造までサポートしている。 シーケンス、データ構造のマッチングの例は、次項以降で説明する。 他にもswitch文との違いとしては、JavaScriptの例で示したdefaultがないことが挙げられる。

先ほどのJavaScriptのswitch文と同じ動きをするものを下記に示す。match文にdefaultという命令は無いので、case _という記述で代用している。 また、JavaScriptのswitch文(上記)では明示的にbreakを入れないとswitch文を抜けることができないが、 Pythonのmatch文(下記)では、matchしたcase文のみが実行され、match文を抜けるという特徴がある。 まずは、この辺りの違いを確実に抑えておこう。

Pythonのmatch文

Pythonのmatch文

2.シーケンスマッチ

ここでは、Pythonのmatch文の長所とも言える、シーケンスマッチについて説明する。 これは、switch文では対応していない機能である。 Pythonのmatch文において、シーケンスをサポートするというのは、 リストやタプルなどのシーケンス型のデータ構造を扱う際の柔軟なパターンマッチングが可能であることを意味する。

以下に、シーケンスに関するパターンマッチングの例を示す。 下記は、Pythonのリストの長さで条件分岐するmatch文である。 最初のcaseでは空である事を判定し、2番目のcaseでは一個要素があることを判定、 3番目のcaseでは2個要素があることを判定している。 4番目のcaseでは、3個以上要素があることを判定したいが、case文の書き方だけでは 要素が3個以上のリストであることと、リスト以外のデータであることを区別できない。 そこはif文の判定で、listのデータかそれ以外かを見分け、listであれば3個以上要素を持っていることを判断している。

リストの長さマッチ

リストの長さマッチ

また、要素の中身についてもmatch文で判定できる。 最初のcaseでは、一番目の要素が1であるかを判定している。 それにより、(最初の要素が1なので)1つめのprint文ではTrueを出力し、(最初の要素が1ではないので)2つめのprint文ではFalseを出力している。

リストの最初が1であるか

リストの最初の要素が1であるか

このように、*_を用いることで、2番目以降の要素はワイルドカードになり、最初の要素が1であるかを判定している。 同様に最後の要素が何であるかを示すには「case [*_ , 1]:」という書き方で判定できる。「case [*_ , 1, 2, 3]:」という連続的な要素の中身判定もできる。 ただし、注意点としては「case [*_ , 1, 2, 3, *_]:」という書き方で、間の要素が何であるかという判定はできない。2個以上ワイルドカード(*)を使うことができないからだ。

ちなみに、タプルに関しても同様にシーケンスマッチを使うことができる。 非常に便利な書き方なので、覚えておこう。

3.データ構造マッチ

データ構造のマッチング判定は、特定のデータ構造やその構造内の要素が、定義されたパターンや条件に合致するかどうかを評価する。 Pythonのmatch文は、このデータ構造のマッチングを効率的に行う機能を提供する。

まずはタプルの例を取り上げる。下記のタプルのマッチング判定では、 タプルの中の2個の要素の中身がint型であるか、2個の要素を持つタプルか、それ以外かを見ている。 print文に書かれた一つ目のタプルでは、タプルの中の2個の要素の中身がint型であることを示し、 print文に書かれた二つ目のタプルでは、int型ではない2個の要素を持つタプルであることを示している。

タプルのマッチング

タプルのマッチング

次にリストの例を取り上げる。 下記のリストのマッチング判定では、 空のリストであるか、最初の要素がint型であるリストか、それ以外かを見ている。 print文に書かれた一つ目のリストは、空のリストであることを示し、 print文に書かれた二つ目のリストでは、最初の要素がint型であるリストを示している。

リストのマッチング

リストのマッチング

次に辞書の例を取り上げる。 下記の辞書のマッチング判定では、 nameがkeyの値が文字列型、ageがkeyの値がint型の辞書であるかどうかを見ている。 print文に書かれた一つ目の辞書は、nameがkeyの値が文字列型、ageがkeyの値がint型の辞書であることを示し、 print文に書かれた二つ目、三つ目の辞書では、それ以外の辞書であることを示している。

辞書のマッチング

辞書のマッチング

最後にClassの例を取り上げる。 下記のClassのマッチング判定では、 コンストラクタのnameの値が文字列型、ageの値がint型かどうかを見ている。 print文に書かれたaliceインスタンスは、nameの値が文字列型、ageの値がint型の辞書であることを示している。 そして、一個目のcaseにマッチするため「Person named Alice aged 30」 をprint文で出力している。

Classのマッチング

Classのマッチング


4.まとめ

今回はPython3.10から搭載されたmatch文について解説した。 match文はswitch文と同じような使い方だけでなく、データ構造やデータの型、内容について判定することができる。 今回のmatch文の登場により、if文ではまとまりにくい、複雑な条件分岐があった場合でも、スマートに判定ができるようになった。 単純な変数の値だけでなく、リスト、タプル、辞書、クラスの中身を判別したいときは、ぜひPythonのmatch文を使ってみよう。


▼参考図書、サイト

 日経ソフトウエア 2023年9月号 日経BP
Python 3.10の新機能(その1) パターンマッチ python Japan
Python3.10の新機能(2) - Pythonにmatch文がやってくる Qiita