【Python】match case(match文)で複数条件を処理する方法

【Python】match case(match文)で複数条件を処理する方法

公開: 更新:



Pythonのmatch case(match文)で複数条件を処理する方法

Pythonの構造的パターンマッチング(match-case)では、複数の条件を簡潔に処理できます。この機能はPython 3.10から導入され、if-elif-else文より複雑な条件分岐をわかりやすく書ける利点があります。match文は値を受け取り複数のcaseと照合し、最初にマッチしたパターンのコードブロックを実行します。

match-case文の構文は値をパターンと比較するシンプルなものですが、複数のパターンを扱う方法も用意されています。特にパイプ記号(|)を使うと、一つのcaseで複数の値に対応できるため、コードの冗長を減らせます。

【サンプルコード】
# 基本的なmatch-caseの使用例(複数条件)
def check_status(status):
    match status:
        case "ready" | "prepared" | "standby":
            return "システムは準備完了です"
        case "running" | "processing":
            return "システムは実行中です"
        case "error" | "failed" | "crashed":
            return "システムはエラーが発生しています"
        case _:
            return "未知の状態です"

# 複数のステータスでテスト
statuses = ["ready", "processing", "failed", "unknown"]
for status in statuses:
    print(f"ステータス '{status}': {check_status(status)}")
【実行結果】
ステータス 'ready': システムは準備完了です
ステータス 'processing': システムは実行中です
ステータス 'failed': システムはエラーが発生しています
ステータス 'unknown': 未知の状態です
行番号 詳細説明
2行目 check_status関数を定義
3行目 match文でstatusを判定開始
4行目 ready prepared standbyをcaseでまとめて処理
5行目 マッチした場合の戻り値をreturn
6行目 running processingをcaseでまとめて処理
7行目 マッチした場合の戻り値をreturn
8行目 error failed crashedをcaseでまとめて処理
9行目 マッチした場合の戻り値をreturn
10行目 どのcaseにもマッチしない場合をcase _で指定
11行目 未知の状態を示す戻り値をreturn
14行目 statusesリストにテスト用のステータスを代入
15行目 statusesをループで取り出す
16行目 ステータスとcheck_statusの結果をprint

【PR】『Python』を学べる企業・個人向けのプログラミングコース

match caseで複数のデータ型に対応する方法

match-case文は単純な値の比較だけではなく、リストやタプル、辞書など複数のデータ型にも対応できるため、データのと内容に応じた分岐をまとめやすくなります。特にOR条件とasキーワードを組み合わせると、似たような型に一度に対応できるので便利です。

複合データ型の場合、アンパック演算子(*)で可変長の要素に対応したり、辞書の特定のキーだけを取り出したりすることもできます。これらを組み合わせると、複雑な構造を扱う際のコードをわかりやすく書けます。

【サンプルコード】
# 複数のデータ型に対応するmatch-case
def process_data(data):
    match data:
        case str(s):
            return f"文字列: {s}の長さは{len(s)}文字です"
        case list() | tuple() as sequence:
            return f"シーケンス: 要素数は{len(sequence)}です"
        case {"name": name, "age": age}:
            return f"ユーザー: {name}さん({age}歳)"
        case {"type": "point", "x": x, "y": y}:
            return f"座標点: ({x}, {y})"
        case _:
            return "未知のデータ型です"

# 様々なデータ型でテスト
test_data = [
    "Python",
    [1, 2, 3, 4],
    (10, 20, 30),
    {"name": "田中", "age": 30},
    {"type": "point", "x": 5, "y": 10},
    {"other": "data"}
]

for data in test_data:
    print(process_data(data))
【実行結果】
文字列: Pythonの長さは6文字です
シーケンス: 要素数は4です
シーケンス: 要素数は3です
ユーザー: 田中さん(30歳)
座標点: (5, 10)
未知のデータ型です
行番号 詳細説明
2行目 process_data関数を定義
3行目 match文でdataを判定開始
4行目 dataが文字列のときの処理
5行目 マッチした文字列の長さ情報を返す
6行目 dataがlistまたはtupleのときの処理
7行目 マッチしたシーケンスの要素数を返す
8行目 dataが辞書でnameとageキーを持つときの処理
9行目 マッチした場合のユーザー情報を返す
10行目 dataが辞書でtypeがpointのときの処理
11行目 座標点の情報を返す
12行目 どのパターンにも当てはまらない場合の処理
14行目 テストデータをリストでまとめて定義
23行目 process_dataの結果をprint

match caseで複数変数を抽出する方法

match-case文では、複雑な構造から複数の変数を同時に抽出できます。ネストされたリストや辞書の特定要素を一括で取り出せるため、データ検証と同時に処理を進めやすいです。

例えばリストの要素数や辞書の特定キーをチェックしながら変数に代入する場合、if文を多用するよりもコードがすっきりするため、大きなJSONやAPIレスポンスを扱うときにも便利です。

【サンプルコード】
# 複数変数を抽出するmatch-case
def analyze_command(command):
    match command:
        case ["GET", path]:
            return f"GETリクエスト: パス '{path}' にアクセスします"
        case ["POST", path, {"content": content, "type": type}]:
            return f"POSTリクエスト: パス '{path}' に {type} 形式で '{content}' を送信します"
        case ["DELETE", path, id]:
            return f"DELETEリクエスト: パス '{path}' のID '{id}' を削除します"
        case ["UPDATE", path, id, {"fields": fields}]:
            return f"UPDATEリクエスト: パス '{path}' のID '{id}' を更新します。フィールド: {fields}"
        case _:
            return "無効なコマンドです"

# 様々なコマンドでテスト
commands = [
    ["GET", "/api/users"],
    ["POST", "/api/comments", {"content": "素晴らしい記事です", "type": "text/plain"}],
    ["DELETE", "/api/posts", "12345"],
    ["UPDATE", "/api/profile", "user123", {"fields": ["name", "email"]}],
    ["INVALID", "command"]
]

for cmd in commands:
    print(analyze_command(cmd))
【実行結果】
GETリクエスト: パス '/api/users' にアクセスします
POSTリクエスト: パス '/api/comments' に text/plain 形式で '素晴らしい記事です' を送信します
DELETEリクエスト: パス '/api/posts' のID '12345' を削除します
UPDATEリクエスト: パス '/api/profile' のID 'user123' を更新します。フィールド: ['name', 'email']
無効なコマンドです
行番号 詳細説明
2行目 analyze_command関数を定義
3行目 match文でcommandを判定開始
4行目 GETコマンドの場合の処理
5行目 マッチした場合の文字列をreturn
6行目 POSTコマンドの場合の処理
7行目 マッチしたときにPOST内容をreturn
8行目 DELETEコマンドの場合の処理
9行目 IDを取得してメッセージをreturn
10行目 UPDATEコマンドの場合の処理
11行目 フィールド情報を含めてreturn
12行目 その他のコマンドは無効と返す
14行目 テストコマンドをリストにまとめる
20行目 analyze_commandで処理して結果をprint

【PR】『Python』を学べる個人・中高生向けのプログラミングコース

match caseでガード節を使用した複数条件を処理する方法

match-case文にはガード節を追加する機能があります。case パターン if 条件の形式で書くと、パターンにマッチした後でさらに条件式を評価できるため、範囲チェックなど複雑な条件をまとめやすくなります。

ガード節はネストの深いif文を書くよりも意図が明確で読みやすいです。複数の型や値に対して、同様の条件を設定したいときにも便利に使えるでしょう。

【サンプルコード】
# ガード節を使用したmatch-case
def categorize_number(n):
    match n:
        case int() | float() as num if num < 0:
            return f"{num}は負の数です"
        case int() as num if num == 0:
            return "ゼロです"
        case int() as num if num > 0 and num % 2 == 0:
            return f"{num}は正の偶数です"
        case int() as num if num > 0:
            return f"{num}は正の奇数です"
        case float() as num if num > 0:
            return f"{num}は正の小数です"
        case _:
            return "数値ではないか、想定外の数値です"

# 年齢と権限によるアクセス制御の例
def check_access(user):
    match user:
        case {"role": "admin"}:
            return "管理者権限でアクセスが許可されています"
        case {"role": "user", "age": age} if age >= 18:
            return "成人ユーザーとしてアクセスが許可されています"
        case {"role": "user", "age": age} if age < 18:
            return "未成年ユーザーには一部コンテンツが制限されています"
        case {"role": role}:
            return f"未知の役割: {role}"
        case _:
            return "ユーザー情報が不完全です"

# テスト用データ
numbers = [-10, 0, 7, 22, 3.14, "string"]
users = [
    {"role": "admin", "name": "管理者", "age": 35},
    {"role": "user", "name": "一般ユーザー1", "age": 25},
    {"role": "user", "name": "一般ユーザー2", "age": 16},
    {"role": "guest"},
    {"name": "不完全なユーザー"}
]

print("--- 数値の分類 ---")
for n in numbers:
    print(f"{n}: {categorize_number(n)}")

print("\n--- アクセス制御 ---")
for user in users:
    print(f"{user}: {check_access(user)}")
【実行結果】
--- 数値の分類 ---
-10: -10は負の数です
0: ゼロです
7: 7は正の奇数です
22: 22は正の偶数です
3.14: 3.14は正の小数です
string: 数値ではないか、想定外の数値です

--- アクセス制御 ---
{'role': 'admin', 'name': '管理者', 'age': 35}: 管理者権限でアクセスが許可されています
{'role': 'user', 'name': '一般ユーザー1', 'age': 25}: 成人ユーザーとしてアクセスが許可されています
{'role': 'user', 'name': '一般ユーザー2', 'age': 16}: 未成年ユーザーには一部コンテンツが制限されています
{'role': 'guest'}: 未知の役割: guest
{'name': '不完全なユーザー'}: ユーザー情報が不完全です
行番号 詳細説明
2行目 categorize_number関数を定義
3行目 match文でnを判定開始
4行目 intまたはfloatで負の数の場合を処理
5行目 マッチした場合に負の数を示す文字列をreturn
6行目 nがintでゼロの場合を処理
7行目 マッチした場合にゼロを示す文字列をreturn
8行目 nが正の偶数の場合を処理
9行目 マッチした場合に正の偶数を示す文字列をreturn
10行目 nが正の奇数の場合を処理
11行目 マッチした場合に正の奇数を示す文字列をreturn
12行目 nがfloatで正の数の場合を処理
13行目 マッチした場合に正の小数を示す文字列をreturn
14行目 どのパターンにも合致しない場合を処理
18行目 check_access関数を定義
19行目 match文でuserを判定開始
20行目 roleがadminの場合を処理
21行目 アクセス許可を示す文字列をreturn
22行目 roleがuserでageが18以上の場合を処理
23行目 成人ユーザーのアクセス許可をreturn
24行目 roleがuserでageが18未満の場合を処理
25行目 未成年ユーザーで制限ありをreturn
26行目 未知の役割を処理
27行目 ユーザー情報が不完全な場合をreturn
31行目 numbersにテスト用の値を用意
32行目 usersにテスト用ユーザー情報を用意
38行目 numbersをループしてcategorize_numberの結果をprint
40行目 アクセス制御の結果をprint

※上記コンテンツの内容やソースコードはAIで確認・デバッグしておりますが、間違いやエラー、脆弱性などがある場合は、コメントよりご報告いただけますと幸いです。

ITやプログラミングに関するコラム


ITやプログラミングに関するニュース

ブログに戻る

コメントを残す

コメントは公開前に承認される必要があることにご注意ください。

コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア 金融業界の業務効率化を加速するニッセイアセットマネジメントの生成AI×GAS活用研修事例 - IT・プログラミングを知って学べるコネクトメディア 【製造業のDX人材育成事例】デジタル人材の即戦力化を実現する、日本ガイシ株式会社の異動者向オンボーディング研修 - ITやプログラミングを知って学べるコネクトメディア フューチャーアーキテクト株式会社が実現した新入社員向けIT研修プログラムでタスクフォース制度が主体的な学びと成長を生み出す - IT・プログラミングを知って学べるコネクトメディア コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【IT新入社員研修】オンラインとオフラインの最適バランスを実現したFutureOneの導入事例 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【新入社員研修】柔軟なハイブリッド型Java研修で実現した新卒20名の成長と成果|サークレイス株式会社 - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/現場により近いところにデジタルを根付かせるDX基礎講座研修|株式会社ブリヂストン - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/業務の効率化・DX推進に向けたIT人材育成への第一歩|株式会社カナエ - ITやプログラミングを知って学べるコネクトメディア 企業・法人向けのIT・プログラミング研修 - ITやプログラミングを知って学べるコネクトメディア

新着記事

対象者別で探す

子供(小学生・中学生・高校生)向け
プログラミング教室検索する

子供(小学生・中学生・高校生)がロボットやプログラミング言語を学ぶことができるオフラインからオンラインスクールを検索、比較することが可能です。

子供(小学生・中学生・高校生)
プログラミング教室検索する

ITやプログラムなどの
最新情報を検索する

日々、新しいITやプログラミング言語の情報が流れていきますが、特定の情報を時系列でニュースやコラムを確認することができます。

ITやプログラムなどの
最新情報を検索する