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 と同じ役割です。
match は Python 3.10 から入った比較的新しい文法です。古い環境では動かないことがあるので、実務で使うときはバージョンを確認します。
matchは「値そのものを見る」分岐に向いています。price >= 1000のような大小比較には向かないので、そこは素直にifを使います。
動きを追ってみる
category_mark("娯楽") を呼んだときの流れは下記のとおりです。
match categoryで、比べる対象が"娯楽"に決まるcase "食費"と照合し、一致しないので次へcase "日用品"も一致せず次へcase "娯楽"で一致し、return "[娯]"で終わる- 残りの
caseは見に行かない
上から順に照合し、最初に当たったものだけが動くという点は elif とまったく同じです。
複数の候補をまとめる
case は | で候補を並べられます。「日用品と交通費は同じ記号でいい」という場合は 1 行にまとめられます。
match category:
case "日用品" | "交通費":
return "[固]"
case _:
return "[他]"elif で書くと or でつなぐところが、match では | になります。今回の課題ではまとめずに 1 つずつ書きます。
elifとmatchは優劣ではなく向き不向きです。候補が 2 つか 3 つならelifのほうが読みやすいこともあります。5 つを超えたあたりからmatchの見通しの良さが効いてきます。
よくある間違い
case _を書き忘れる — どのcaseにも一致しないとmatch全体が素通りされます。関数ならreturnに届かずNoneが返り、テストに落ちます。caseの値をクオートで囲まない —case 食費:と書くと、Pythonは食費という変数名だと解釈します。文字列と比べたいならcase "食費":です。- インデントが 1 段足りない —
matchの中のcaseで 1 段、caseの中身でさらに 1 段下げます。関数の中ならcaseの中身は 12 個分になります。
case _: の _ は変数名として使える普通の名前ですが、match の中では特別扱いされ、必ず一致するワイルドカードになります。
やってみよう
関数 category_mark(category) を実装してください。カテゴリ文字列を受け取り、下記の記号を返します。
食費 なら "[食]"、日用品 なら "[日]"、娯楽 なら "[娯]"、交通費 なら "[交]"、それ以外のどんな文字列でも "[他]" です。かっこは半角の [ と ] です。
match で書いてみてください。書き終わったら elif 版に直してみると、どちらが読みやすいか自分の感覚で比べられます。
要件
- 関数名は category_mark で、引数は category の 1 つ
- 食費 / 日用品 / 娯楽 / 交通費 にそれぞれ [食] / [日] / [娯] / [交] を return する
- 上のどれにも当てはまらない文字列にはすべて [他] を return する
- かっこは半角の [ と ] を使う
入出力例
category_mark("食費") → "[食]"
category_mark("日用品") → "[日]"
category_mark("娯楽") → "[娯]"
category_mark("交通費") → "[交]"
category_mark("その他") → "[他]"
category_mark("医療費") → "[他]"
category_mark("") → "[他]"