Skip to content

3.3 構造的パターンマッチ

Python 3.10で追加された matchcase による「構造的パターンマッチ(Structural Pattern Matching)」は、複雑なデータ構造に対する条件分岐を、従来の if 文よりもシンプルかつ直感的に記述できる強力な機能です。

本記事では、構造的パターンマッチの基本構文から実践的な使い方までをわかりやすく解説します。

1. 構造的パターンマッチの基本

Section titled “1. 構造的パターンマッチの基本”

match 文に指定した式(subject)を評価し、その結果を上から順番に case 節に書かれたパターンと比較します。パターンと一致した場合、そのブロックに関連付けられた処理を実行し、match 文を抜けます。

match subject:
case <pattern_1>:
<action_1>
case <pattern_2>:
<action_2>
case _: # ワイルドカードパターン
<action_wildcard>

どのパターンとも一致しなかった場合のデフォルトの処理は、ワイルドカードパターン(_)で定義します(if 文における else に相当します)。

構造的パターンマッチの真価は、単純な値の比較だけでなく、データ構造や型に基づいたマッチングができる点にあります。代表的なパターンを紹介します。

2.1 リテラルパターンとワイルドカード

Section titled “2.1 リテラルパターンとワイルドカード”

最も基本的なパターンです。任意の文字列、数値、NoneTrueFalse などと直接比較します。 どれにもマッチしない場合は case _:(ワイルドカードパターン)が実行されます。

2.2 ORパターンとキャプチャーパターン

Section titled “2.2 ORパターンとキャプチャーパターン”
  • ORパターン (|): | で区切られた複数のパターンのいずれかにマッチすれば処理を実行します(例:case "coffee" | "tea":)。
  • キャプチャーパターン: マッチした値を変数として取り込み(キャプチャーし)、後続の処理で変数名でアクセスできるようにします。
case value: # subjectのすべての値を取り込む
return f"値は{value}です"

2.3 シーケンスパターンとマッピングパターン

Section titled “2.3 シーケンスパターンとマッピングパターン”

リストやタプル、辞書といったデータ構造の「形」と「中身」でマッチングを行います。

  • シーケンスパターン: リストやタプルなどの要素数や値でマッチさせます。* を使った要素のアンパックも可能です。
# 任意の数の要素をアンパックして受け取る例
case ["drink", *drinks, size]:
  • マッピングパターン: 辞書のキーと値のペアでマッチさせます。“ を使って指定した変数に辞書形式で残りの要素を受け取ることもできます。
case {"drink": drink, "size": size}:

2.4 クラスパターンとASパターン

Section titled “2.4 クラスパターンとASパターン”

任意のクラスのインスタンスであるか、またその属性値がどうなっているかでマッチングを行います。str()int() のような組み込み型の判定にも使えます。

case Drink(drink, ("S" | "M" | "L") as size):
# Drinkクラスのインスタンスで、属性が条件に合うか判定し、sizeに代入

ここでは ASパターンas 変数名)を組み合わせることで、ORパターンなどでマッチした特定の値を後から参照できるように変数に取り込んでいます。

3. ガード (Guard) による条件の追加

Section titled “3. ガード (Guard) による条件の追加”

各パターンの後ろに if 文(ガード)を追加することで、パターンがマッチした上で、さらに条件式が True の場合にのみ、その case 節のコードを実行させることができます。

match subject:
case ("people", int(num)) if num <= 0: # ガードで数値の範囲を指定
return "正しい人数を指定してください"
case ("people", int(num)) if num <= 2:
return f"{num}名様ですね。カウンター席へご案内します"

4. 知っておくべき注意点とエラー

Section titled “4. 知っておくべき注意点とエラー”

パターンは上から順番に評価され、最初にマッチしたパターンの処理を実行して終了します。 そのため、条件の広いパターンを上に書きすぎると、下にある特定の詳細な条件が評価されなくなってしまうため、順番には注意が必要です。

4.2 リテラルパターンに f-string は使えない

Section titled “4.2 リテラルパターンに f-string は使えない”

パターンの文字列として、f-string や t-string を指定することはできません。これらをパターンに指定すると SyntaxError が発生するため、必ず文字列リテラルを使用してください。

matchcase_ の3つは「ソフトキーワード」として実装されています。これらは構造的パターンマッチの構文内でのみキーワードとして動作し、通常の変数名などの識別子としても既存コードとの互換性を保つために使用可能です。