Python速習ガイド - ステップ2 制御フロー (6) - パターンマッチング (match文)
- 本講座は、Pythonプログラミングの基礎を手を動かしながら最速で身につけるための講座です。
- 「スタイルガイド」では、Pythonできれいなコードを書くためのガイドライン(PEP8)で紹介されている内容を主に記載しています。
- 各コードは実行して結果を確認することができます。
ページの再読み込みで元の内容に戻りますので、自由にいじってみてください。
「ステップ2 制御フロー」の続きです。
2.3. パターンマッチング (match
文)
パターンマッチングは、Python 3.10から導入された、値のパターンに基づいて条件分岐を行う機能です。
2.3.1. match
文の基本
match
文は、式の値を複数のパターンと照合し、一致したパターンのブロックを実行します。
match
で指定した式(status_code
)が順番に各case
のパターンと比較されます- 最初に一致した
case
のブロックのみが実行されます case _:
は常にマッチするデフォルトのケースで、どのパターンにもマッチしない場合に実行されます
2.3.2. パターンの種類
match
文では、様々な種類のパターンを使用できます。
基本的なパターン
リテラルパターン
定数値と完全一致するかどうかを確認します。
キャプチャパターン
パターンに変数を使用すると、パターンに一致した値が変数に代入されます。
(この変数は対象ケースのブロック内のみで使用可能です。)
ワイルドカードパターン
キャプチャパターンで見たように、変数は任意のパターンにマッチします。
特にその値を使用しない場合は、変数名としてアンダースコア(_
)を使用します。
構造に関するパターン
シーケンスパターン
シーケンスパターンは、リストやタプルなど順序付きのコレクションに対して、中の要素をパターンとしてマッチングするための仕組みです。
マッピングパターン
シーケンスパターンと同様に、辞書に関してもパターンマッチングが使用可能です:
クラスパターン
リストや辞書だけでなく、任意のクラスにパターンマッチングを行う機能もあります。
クラスに関しては本講座では未解説のため、簡単な解説を以下に記載します。
クラスとは、データとその振る舞いをまとめたデータ構造です。
例えば、2次元の点のクラスは以下のように定義できます。
上記クラスを使ったマッチングは以下のようにして書くことができます:
装飾付きパターン
OR パターン
|
(パイプ)を使用して複数のパターンを一度に指定できます。
これにより、類似したケースをまとめて扱うことができます。
AS パターン
パターン全体を1つの変数に代入したい場合に、as
を用いたパターンが利用できます。
ORパターンと組み合わせた以下のような使い方もできます:
ガード付きパターン
if
を使用して追加の条件を指定できます。
match
文で使用される if <条件式>
の部分をガードといいます。
「キャプチャパターン」で見た通り、match
文の case
で変数名を指定すると、その変数にマッチ対象の値が代入されます。
たとえば、次のようなコードは一見、定数(NOT_FOUND
)と比較しているように見えますが、
実際にはmatch
文内でNOT_FOUND
という新しい変数を作成して値を代入しています:
意図した動作を行うには、ガード(if
)を使用して値を比較します:
2.3.3. パターンマッチングまとめ
Python 3.10で導入されたmatch
文は、値のパターンに基づいて条件分岐を行う強力な機能です。
match文の主な特徴:
- 式の値を複数のパターンと照合し、一致したパターンのブロックを実行
- パターンは上から順に評価され、最初に一致したパターンのみが実行される
- 柔軟なパターン記述により、複雑な条件分岐をシンプルに表現可能
- if-elif-elseによる条件分岐よりも、データ構造に対する処理を直感的に記述できる
パターンの種類:
カテゴリ | パターン | 説明 | 例 |
---|---|---|---|
基本的なパターン | リテラルパターン | 定数値と完全一致 | case 200: |
キャプチャパターン | マッチした値を変数に代入 | case value: |
|
ワイルドカードパターン | 任意の値にマッチ(_ ) |
case _: |
|
構造に関するパターン | シーケンスパターン | リストやタプルの構造マッチング | case [x, y]: |
マッピングパターン | 辞書の構造マッチング | case {"name": name}: |
|
クラスパターン | オブジェクトの属性マッチング | case Point(x=0, y=y): |
|
修飾付きパターン | ORパターン | 複数パターンの選択 | case "A" | "B": |
ASパターン | マッチ対象全体を変数に割当 | case (x, y) as point: |
|
ガード付きパターン | 追加条件を指定 | case x if x > 0: |
プレイヤーの入力コマンドに応じて処理を行うゲームシステムを作りましょう。
今回は各コマンドに対して、指定された文字列を出力するプログラムにします。
コマンドは以下の形式で与えられます:
- 移動コマンド:
["move", <方向>, <歩数>]
(例:["move", "north", 5]
)- => 「
<方向>
方向に<歩数>
歩移動します」
- => 「
- 攻撃コマンド:
["attack", <武器>]
(例:["attack", "sword"]
)- => 「
<武器>
で攻撃します」
- => 「
- アイテム使用:
["use", <アイテム>]
(例:["use", "potion"]
)- => 「
<アイテム>
を使用します」
- => 「
- ヘルプ表示:
["help"]
- => 「ヘルプメニューを表示します」
- ゲーム終了:
["quit"]
または["exit"]
- => 「ゲームを終了します」
- その他のコマンド
- => 「無効なコマンドです」
match
文を使って、各コマンドに対応するメッセージを表示するコードを書きましょう。
解答例
天気データ(天気と気温のタプル)に基づいて、適切な服装のアドバイスを表示するシステムを作りましょう。
"雨"
かつ10
℃ 未満 => 「雨が降っています。レインコートを着用しましょう。」"雨"
かつ10
℃ 以上 => 「雨が降っています。傘を忘れずに持っていきましょう。」"雪"
=> 「雪が降っています。厚手のコートと手袋を着用しましょう。」"晴れ"
または"曇り"
かつ30
℃ 以上 => 「天気は<天気>
で気温が高いです(<気温>℃
)。半袖を着用しましょう。」"晴れ"
かつ15
℃未満 => 「晴れていますが気温が低めです(<気温>℃
)。上着を持っていきましょう。」"曇り"
かつ15
℃未満 => 「曇りで肌寒いです(<気温>℃
)。ジャケットを着用しましょう。」- その他 => 「
<天気>
で<気温>
℃です。季節にあった服装をしましょう。」
解答例
ショッピングカートの商品リストに対して、パターンマッチングを使って合計金額を計算しましょう。
ただし、商品リストは (商品名, 数量)
または (商品名, 数量, 割引率)
という形のタプルです。