スポンサーリンク

Pythonのパターンマッチとは?基本から実践まで初心者向けに解説!

Python入門

1. はじめに|パターンマッチ構文ってなに?

Pythonを使っていると、「ある値に応じて処理を分けたいな〜」と思うこと、よくありますよね。たとえば「変数が1だったら〇〇、2だったら△△、それ以外は□□」といったような場面。これまでは ifelif を使って条件分岐していました。

でもPython 3.10からは、もっとスマートに書ける新しい文法が登場しました。それが**パターンマッチ構文(match-case構文)**です!

この構文を使えば、「変数の中身がどんなパターンに当てはまるか?」で処理を分けることができます。しかも、リストや辞書、オブジェクトといったちょっと複雑なデータ構造に対しても、シンプルで分かりやすいコードが書けるんです。


たとえば、こんな感じ👇

match x:
case 1:
print("xは1です")
case 2:
print("xは2です")
case _:
print("xは1でも2でもありません")

これ、まるで他の言語の switch-case に似ていると思った人もいるかもしれません。でも実は、Pythonのパターンマッチはもっと進化した書き方ができるんです!

このあと、

  • どうやって書くの?
  • if文との違いは?
  • リストや辞書でも使えるの?
  • クラスと組み合わせるとどうなるの?

といった疑問を、やさしく、ていねいに解説していきます。

Pythonをもっと読みやすく、キレイに書きたい人には、ぜひ知っておいてほしい便利な機能ですよ!




2. パターンマッチ構文の基本

ここからは、Python 3.10で使える「パターンマッチ構文(match-case)」の書き方の基本を見ていきましょう!

📌 まずは「match」と「case」

パターンマッチ構文の主役は matchcase の2つです。書き方はこんな感じです👇

match 変数:
case パターン1:
処理1
case パターン2:
処理2
case _:
それ以外のときの処理

match のあとに調べたい「変数(値)」を書いて、その中で case を使って「このパターンならこの処理!」と分けていきます。

たとえば、こんなコード:

x = 2

match x:
case 1:
print("xは1です")
case 2:
print("xは2です")
case _:
print("xは1でも2でもありません")

このコードを実行すると、x の値が2なので「xは2です」と表示されます!

🔄 if文とどう違うの?

同じことは if を使ってもできますよね?でも、パターンマッチのすごいところは、もっと複雑なパターンでもスッキリ書けることなんです。

特に、次のようなときに効果を発揮します:

  • リストや辞書の中身を見て分岐したい
  • オブジェクトの種類や属性をチェックしたい
  • 条件が多すぎて if 文が読みにくくなってきた

あとで詳しく紹介しますが、「こういう形のデータが来たら、こう処理しよう!」というのを見たまま分かる形で書けるのが最大のメリットです。

🌟「それ以外」は case _: で書こう

case _: は、どのパターンにも当てはまらなかったときの「その他」の処理です。これは if 文の else にあたる部分ですね。

match x:
case 1:
print("xは1です")
case _:
print("xは1ではありません")

このように書いておけば、すべてのパターンをカバーできます!




3. 具体的な使い方とパターンの種類

ここからは、パターンマッチ構文で使える「いろんなパターン」の書き方を見ていきましょう!基本の case に、ちょっとした工夫を加えることで、もっと柔軟な条件分けができるようになります。


🟨 ORパターン(|)

「AかBどっちかに当てはまればOK!」というときは、縦線(パイプ)| を使います。

x = 0

match x:
case 0 | 1:
print("xは0か1です")
case _:
print("xは0でも1でもありません")

このように、case 0 | 1: と書くことで、0または1のどちらかならマッチします。


🟩 ワイルドカード(_)

これは前の章でも紹介しましたが、「どれにも当てはまらないとき」に使う便利なパターンです。

case _:
print("どのパターンにも当てはまりませんでした")

ちなみに case _:_ という記号は「なんでもOK」「無視するよ」って意味を持っています。


🟦 変数への代入パターン

case の中で変数を使うと、マッチした値をその変数に代入できます!

match x:
case y:
print(f"xの値は {y} です")

でも注意!この書き方は「常にマッチしてしまう」ので、一番最後(case _ の前)に書くのがベストです。


🟥 ガード条件(if)

「パターンが合っていて、さらに条件も満たしている場合だけ!」というときは、caseif をつけて書けます。

x = 10

match x:
case y if y > 5:
print("5より大きいです")
case _:
print("5以下です")

ここでは、yx の値を入れて、それが5より大きければマッチします。

ガード条件を使うと、「〇〇の場合、ただし××なときだけ」という細かい条件分岐もスッキリ書けます!




4. 辞書やリストでの応用例

ここでは、**辞書(dict)やリスト(list)**を対象にしたパターンマッチの書き方を見ていきましょう!

複雑なデータ構造でも、「どのパターンに合っているか?」で処理を分けられるのが、パターンマッチ構文の強みです。


📘 辞書に対するパターンマッチ

まずは辞書の例から。

response = {'status': 200, 'lat': 35.68}

match response:
case {'status': 200, 'lat': x}:
print(f"緯度は {x} 度です")
case {'status': 404}:
print("データが見つかりませんでした")
case _:
print("想定外のレスポンスです")

このように、case の中に辞書のキーとパターンを並べて書くことで、

  • キーが存在するか?
  • その値がパターンに合うか?

を同時にチェックできます。

しかも lat: x のように書けば、その値を変数 x に代入することもできるんです!これ、if文でやるとけっこう長くなるので、かなりスッキリ書けますね。


📗 リストに対するパターンマッチ

次はリスト。リストでは、要素の個数や値によって分岐することができます。

coords = [0, 0]

match coords:
case []:
print("リストは空です")
case [0]:
print("1次元の原点です")
case [0, 0]:
print("2次元の原点です")
case [x, y]:
print(f"2次元の座標は x={x}, y={y} です")
case _:
print("対応していない形式のリストです")

このコードでは、

  • 要素数0:空リスト
  • 要素1個で0:1次元の原点
  • 要素2個で両方0:2次元の原点
  • 要素2個で他の値:その座標を表示

というように、パターンで分岐しながら、変数に代入して使うことができます。


✅ if文との比較

例えば、これを if 文で書くとこんな感じになります:

if coords == []:
print("空です")
elif coords == [0]:
print("1次元の原点です")
elif coords == [0, 0]:
print("2次元の原点です")
elif len(coords) == 2:
x, y = coords
print(f"x={x}, y={y}")
else:
print("その他")

ね?ちょっと長くて読みにくいですよね。

match-case を使えば、データの形と処理がひと目でわかるので、読みやすさがグッと上がります!




5. クラス・データクラスとの連携

Pythonでは、独自のクラスやデータクラスを使ってデータを扱うことがよくありますよね。
実は、パターンマッチ構文はクラスのインスタンスにも使えるんです!

「このオブジェクトは〇〇というクラスのものかどうか」「中の値が特定の条件に合っているか」を、めちゃくちゃスマートに書けるようになります!


👓 クラスの型チェック

まずは、変数の中身がどの型のオブジェクトかを判定する例です。

obj = "こんにちは"

match obj:
case str():
print("これは文字列です")
case int():
print("これは整数です")
case _:
print("その他の型です")

このように str()int() と書くことで、そのクラスのインスタンスかどうかをチェックできます。
これは isinstance(obj, str) と同じようなことをしてくれてます。


📦 データクラスと組み合わせると最強!

さらに、@dataclass を使ったデータクラスと組み合わせると、中の値まで条件としてマッチングできちゃいます!

from dataclasses import dataclass

@dataclass
class Teacher:
name: str
is_principal: bool

@dataclass
class Student:
name: str

person = Teacher(name="田中", is_principal=True)

match person:
case Student(name=n):
print(f"{n} さん、こんにちは!")
case Teacher(name=n, is_principal=True):
print(f"{n} 校長先生、こんにちは!")
case Teacher(name=n):
print(f"{n} 先生、こんにちは!")
case _:
print("誰か分かりません")

上のコードでは、person の中身がどのクラスのインスタンスかだけでなく、中の変数(属性)の値も見て分岐できています。

しかも、name=n のようにして、値を変数に代入することも可能です。すごい便利!

ちなみに、@dataclass を使っていない普通のクラスでも使えるには使えますが、インスタンス変数を直接パターンマッチで取り出すのは書き方がちょっとややこしいです。

そのため、パターンマッチをクラスと一緒に使いたい場合は、データクラスにしておくと圧倒的にラクになります!




6. 注意点とエラーになりやすい書き方

パターンマッチ構文はとっても便利ですが、ちょっとした書き間違いでエラーが出てしまうこともあります。

ここでは、初心者の方がつまずきやすいポイントをまとめて紹介します。これを読めば、ミスを減らしてスムーズに使えるようになりますよ!


❌ case 1 + 1: はNG!

これはよくある間違い!

match x:
case 1 + 1: # ❌ これは式なのでエラーになります
print("2です")

case のあとに書けるのは「パターン」であって、「式」ではありません。
1 + 1 のような計算式は書けないんです。

👉 正しくはこう書きましょう:

case 2:
print("2です")

❌ 変数を使うときは注意!

こんなコードも要注意です:

x = 10

match x:
case y:
print(f"y = {y}")

このコード、一見すると「xの値がyと同じとき」だけ実行されそうに見えますよね?
でも実際は、このcase y:は常にマッチします!

なぜかというと、y はここで**「新しく作られる変数」**だからです。
つまり「何にでもマッチして、その値をyに代入する」という意味になります。

これは使いどころが限られるので、基本的には**case _:の前の最後の選択肢**として使うのがよいです。


⚠ リスト・辞書の要素数は正確に!

リストや辞書をマッチさせるとき、パターンの形が違うとマッチしません

match [1, 2, 3]:
case [a, b]:
print(a, b) # ❌ 要素数が違うのでマッチしない!

こうなると、スキップされてしまいます。
マッチさせるときは、要素数が合っているかをちゃんと確認しましょう。


✅ ガード条件の変数名に注意!

if 条件(ガード)で使う変数は、ちゃんとそのパターン内で定義されていることが前提です。

match [1, 2]:
case [x] if x > 0: # ❌ xは定義されてないのでエラー
print(x)

この場合は [x] という1要素のリストしかマッチしないので、[1, 2] には合いません。
結果として、x が存在しない状態で if に入ってしまいエラーになります。


🧠 まとめ:よくある間違いを避けよう!

ミス例正しい対処法
case 1 + 1式ではなく値(例:case 2)を書く
case y:常にマッチするので注意。最後の手段に
要素数が違うリストや辞書の形を正確に合わせる
未定義の変数をガード条件に使うちゃんとパターン内で変数を定義しておく



7. パターンマッチ構文を使うための準備

ここまでで、パターンマッチ構文の使い方はバッチリわかってきたと思います!
でも…実はこの機能、Pythonのバージョンによっては使えないってご存知でしたか?

そう、Python 3.10以上じゃないと使えないんです!


🐍 Pythonのバージョンを確認しよう

まずは、いま自分のPCに入っているPythonのバージョンを確認してみましょう。

ターミナル(コマンドプロンプト)で、以下のコマンドを入力してください:

python --version

または、

python3 --version

と表示されたら、たとえばこう返ってきます:

Python 3.9.13

この場合、バージョンが「3.10未満」なのでパターンマッチ構文は使えません!


✅ Python 3.10にアップデートする方法

💻 方法①:公式サイトからインストール

  • Python公式サイト にアクセス
  • ダウンロードページから「Python 3.10.x(またはそれ以上)」をダウンロード
  • そのままインストールしてOK!

🧪 方法②:pyenvを使う(Mac/Linuxの人におすすめ)

pyenv install 3.10.13
pyenv global 3.10.13

これで、好きなバージョンのPythonを簡単に切り替えられます!

📦 方法③:Anaconda(conda)を使ってる人

conda install python=3.10

仮想環境を作っている場合は、環境ごとにバージョンを設定できます。


🛠 IDE(PyCharmやVS Code)でもバージョン切り替えを!

パターンマッチ構文を使いたいのに、エラーが出てしまう場合は、

  • Pythonインタープリターのバージョンが古い
  • 仮想環境が3.10未満

になっていないかを確認しましょう。

特に PyCharmを使っている人 は、プロジェクトの設定から「Python Interpreter」を3.10以上に変更しておくのがポイントです!

Python 3.10に切り替われば、あとはこれまで紹介したとおり、match-case構文を自由に使えるようになります!




8. まとめ|パターンマッチでコードがスッキリ!

Python 3.10で登場した「パターンマッチ構文(match-case)」は、
これまでの ifelif では書きづらかった処理を、シンプルで読みやすくしてくれる新しいツールです。

特に、以下のような場面で真価を発揮します:

  • リストや辞書などの複雑なデータ構造の分岐処理
  • クラスやデータクラスとの連携による柔軟な条件判定
  • if 文が何段にも重なって、コードがゴチャゴチャしてきたとき!

しかも、使い方に慣れてくると、「あっ、ここパターンマッチで書けるじゃん!」と気づけるようになります。

Pythonでの開発をもっと楽しく、読みやすく、スッキリ書きたい人は、ぜひパターンマッチ構文を取り入れてみてくださいね!


よくある質問(Q&A)

Q
match-case は Python 3.10 じゃないと使えませんか?
A

はい、match-case 構文は Python 3.10以降専用の機能です。3.9以前のバージョンでは使用できないので注意しましょう。

Q
if 文と比べて何がいいの?
A

パターンマッチ構文のほうが、複雑なデータ構造を扱うときにスッキリ書けるのが大きなメリットです。
たとえば、辞書やリスト、データクラスなどの分岐処理が格段に見やすくなります。

Q
データクラスじゃないクラスでも使えるの?
A

使えます。ただし、普通のクラスではパターンマッチで属性の値を直接扱うのが少し難しいので、@dataclass を使うのがおすすめです。

※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。

※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。

スポンサーリンク