match文

このレッスンで作るもの — match 文でカテゴリごとの記号を出し分ける category_mark を作ります。elif の長い連なりを整理する道具です。

match 文

おこづかい帳のカテゴリは 食費 日用品 娯楽 交通費 その他 の 5 種類です。一覧を表示するときに、カテゴリごとに短い記号を頭に付けたいとします。

elif で書くと、こうなります。

def category_mark(category): if category == "食費": return "[食]" elif category == "日用品": return "[日]" elif category == "娯楽": return "[娯]" elif category == "交通費": return "[交]" else: return "[他]"

間違ってはいませんが、category == を 4 回も書いています。同じ 1 つの値を、複数の候補と突き合わせる だけの分岐なら、match 文のほうが短く書けます。

文法を確認する

match のうしろに調べたい値を書き、case のうしろに候補を並べます。行末はどちらもコロンです。

def category_mark(category): match category: case "食費": return "[食]" case "日用品": return "[日]" case "娯楽": return "[娯]" case "交通費": return "[交]" case _: return "[他]"

最後の case _ のアンダースコアは ワイルドカード と呼ばれ、「上のどれにも当てはまらなかったもの全部」を受け止めます。elif の連なりにおける else と同じ役割です。

matchPython 3.10 から入った比較的新しい文法です。古い環境では動かないことがあるので、実務で使うときはバージョンを確認します。

match は「値そのものを見る」分岐に向いています。price >= 1000 のような大小比較には向かないので、そこは素直に if を使います。

動きを追ってみる

category_mark("娯楽") を呼んだときの流れは下記のとおりです。

  1. match category で、比べる対象が "娯楽" に決まる
  2. case "食費" と照合し、一致しないので次へ
  3. case "日用品" も一致せず次へ
  4. case "娯楽" で一致し、return "[娯]" で終わる
  5. 残りの case は見に行かない

上から順に照合し、最初に当たったものだけが動くという点は elif とまったく同じです。

diagram (will load when visible)

複数の候補をまとめる

case| で候補を並べられます。「日用品と交通費は同じ記号でいい」という場合は 1 行にまとめられます。

match category: case "日用品" | "交通費": return "[固]" case _: return "[他]"

elif で書くと or でつなぐところが、match では | になります。今回の課題ではまとめずに 1 つずつ書きます。

elifmatch は優劣ではなく向き不向きです。候補が 2 つか 3 つなら elif のほうが読みやすいこともあります。5 つを超えたあたりから match の見通しの良さが効いてきます。

よくある間違い

  1. case _ を書き忘れる — どの case にも一致しないと match 全体が素通りされます。関数なら return に届かず None が返り、テストに落ちます。
  2. case の値をクオートで囲まないcase 食費: と書くと、Python食費 という変数名だと解釈します。文字列と比べたいなら case "食費": です。
  3. インデントが 1 段足りないmatch の中の case で 1 段、case の中身でさらに 1 段下げます。関数の中なら case の中身は 12 個分になります。

case _:_ は変数名として使える普通の名前ですが、match の中では特別扱いされ、必ず一致するワイルドカードになります。

やってみよう

関数 category_mark(category) を実装してください。カテゴリ文字列を受け取り、下記の記号を返します。

食費 なら "[食]"日用品 なら "[日]"娯楽 なら "[娯]"交通費 なら "[交]"、それ以外のどんな文字列でも "[他]" です。かっこは半角の [] です。

match で書いてみてください。書き終わったら elif 版に直してみると、どちらが読みやすいか自分の感覚で比べられます。

要件

  1. 関数名は category_mark で、引数は category の 1 つ
  2. 食費 / 日用品 / 娯楽 / 交通費 にそれぞれ [食] / [日] / [娯] / [交] を return する
  3. 上のどれにも当てはまらない文字列にはすべて [他] を return する
  4. かっこは半角の [ と ] を使う

入出力例

category_mark("食費")"[食]" category_mark("日用品")"[日]" category_mark("娯楽")"[娯]" category_mark("交通費")"[交]" category_mark("その他")"[他]" category_mark("医療費")"[他]" category_mark("")"[他]"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.py
main.py
学習モード

メモ

match文

⌘S で保存