LoginSignup
42
22

More than 1 year has passed since last update.

python 3.10からの新機能 match - case を使ったIF文置き換えの紹介

Last updated at Posted at 2021-12-08

この記事は Python Advent Calendar 8日目 の記事となります。

はじめに

今年開催されたPyConJP 2021にてキーノートセッションされていたブラント・ブーカー氏の発表にあった、「match - case」構文による条件分岐について、 Pythonistaが馴染み薄いかと思いこの場で紹介しようと思った次第です。

image.png
↑は PyConJP 2021 振り返り会 にて発表した際の資料より。

match - case 構文とは

端的に言うなら値に応じた処理の分岐に使用する構文。条件分岐が厳密に定められることや、条件が入れ子になってしまった場合にもスッキリとまとまる(言い方を変えるなら波動拳みたいにはなりにくくなる)こと、パターンが柔軟なことがあげられます。

具体的な使い方については、多くのPythonistaが記事にしていただいているのでそちらを見ていただくことにしましょう。

置き換えの紹介

fizzbuzz問題

有名な問題です。1から100までの数字の内、3の倍数ならFizz、5の倍数ならBuzz、両方に当てはまるならFizzBuzzを返す問題です。

シンプルにif文を使うと以下のコードになります。

for i in range(1, 101):
    if i % 3 == 0 and i % 5 == 0:
        print("FizzBuzz")
    elif i % 3 == 0:
        print("Fizz")
    elif i % 5 == 0:
        print("Buzz")
    else:
        print(i)

これがmatch - case構文だとこうなります。

for i in range(1,101):
    match i:
        case i if i % 3 == 0 and i % 5 == 0:
            print('FizzBuzz')
        case i if i % 5 == 0:
            print('Buzz')    
        case i if i % 3 == 0:
            print('Fizz')
        case _:
            print(i)

あれ?これじゃ別にmatch - case構文である必要はないのでは?と思った方がいると思いますので、視点を変えていきましょう。
(ちなみに上記のようにcaseに条件をつけるやり方をifステートメントみたいに呼びます)

HTTPステータスを分岐させる

HTTPステータスが200ならOK、404ならNot Found, 334なら なんでや阪神関係ないやろ と返すようなコードを書いてみましょう。

if文

http_status = 404

if http_status == 200:
    print("OK")
elif http_status == 404:
    print("Not Found")
elif http_status == 334:
    print("なんでや阪神関係ないやろ")

match - case構文

http_status = 404

match http_status:
    case 200:
        print("OK")
    case 404:
         print("Not Found")
    case 334:
         print("なんでや阪神関係ないやろ")

match - case 構文のほうが条件に必要な変数の記載がない分、スッキリと見えませんか?

入力された座標によって条件を変化させる

X座標とY座標を持ったリストを受け取ったときに、X座標が0から離れている場合、Y座標が0から離れている場合、両方離れている場合で条件を変化させるようなプログラムを書きます。

if文

point = (33, 4)
if point[0] == 0 and point[1] == 0:
    print("原点")
if point[0] == 0 and point[1] != 0:
    print(f"Y={y}")
if point[0] != 0 and point[1] == 0:
    print(f"X={x}")
if point[0] != 0 and point[1] != 0:
    print(f"X={x}, Y={y}")
else:
    print("座標ではありません")

match - case 文

point = (33, 4)
match point:
    case (0, 0):
        print("原点")
    case (0, y):
        print(f"Y={y}")
    case (x, 0):
        print(f"X={x}")
    case (x, y):
        print(f"X={x}, Y={y}")
    case _:
        print("座標ではありません")

match - caseでは受け取る値をそのままcase上で変数に入れて、分岐先で使用することができます。またcase文中の _ はワイルドカード扱いとなり、条件以外を吸収してくれます。

まとめ

3つの例題を通してmatch - case文を書いてみましたが、if文との使い分けるポイントは、

  • 計算が既にされたもの もしくは カテゴリ名などの文字列 の分岐
  • 分岐する条件がリストの中身などといったデータ構造になる場合

にmatch - case構文に置き換えることで、可読性を高めたり、より複雑な分岐をスマートに書くことができるのではないかと思います。無理して使う必要は決してないと思いますが、「if文で書くには冗長だなぁ」と思ったときに検討してみると良いかと思います。

42
22
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
22