条件の組み合わせ

このレッスンで作るもの — 曜日と金額の 2 つを同時に見る weekend_alert を作り、if のネストと and のどちらが読みやすいかを比べます。

条件の組み合わせ

ここまでの分岐は、見ていた材料が price の 1 つだけでした。ところが実際には「土日で、しかも 3000 円以上」のように 2 つの条件が同時に成り立つか を見たい場面が出てきます。

書き方は 2 通りあります。if の中にもう 1 つ if を入れる ネスト と、and で 1 つの条件にまとめるやり方です。

ネストで書く

if の中身にはどんな処理でも書けるので、当然 if も書けます。

def weekend_alert(day, price): if day == "土" or day == "日": if price >= 3000: return "週末の使いすぎ" return "週末の支出" return "平日の支出"

外側の if で曜日を、内側の if で金額を見ています。内側に入れるのは、外側が True だったときだけです。インデントは def で 4 つ、外側の if で 8 つ、内側の if で 12 つと深くなっていきます。

ネストが深くなると、その行が「どの条件を通り抜けてきたのか」を頭の中で覚えておく必要が増えます。3 段以上になったら書き方を疑ってください。

and で書く

「週末の使いすぎ」だけを取り出すなら、2 つの条件を and でつないで平らに書けます。

def weekend_alert(day, price): is_weekend = day == "土" or day == "日" if is_weekend and price >= 3000: return "週末の使いすぎ" elif is_weekend: return "週末の支出" return "平日の支出"

and は第 3 章で扱った論理演算子で、左右の両方が True のときだけ True になります。条件に名前を付けて is_weekend という変数に入れておくと、同じ判定を 2 回書かずに済みます。

diagram (will load when visible)

図にすると、ネスト版も and 版も通る道はまったく同じです。違うのは書き方だけで、結果は 1 文字も変わりません。

どちらが読みやすいか

答えは「場合による」ですが、目安はあります。

  • and が向くとき — 2 つの条件がそろったときの処理が 1 つだけ。平らに書けて分かりやすい
  • ネストが向くとき — 外側の条件の中に、内側で分かれる処理が複数ある

今回のように「週末のとき」の中で 2 つに分かれるなら、ネストのほうが構造をそのまま写せます。一方「週末かつ高額のときだけ警告」であれば and 一択です。

迷ったら「同じ条件を 2 回書いていないか」を見ます。書いていたらネスト、書いていなければ and が素直です。

動きを追ってみる

weekend_alert("土", 5000) のネスト版の流れは下記のとおりです。

  1. day == "土"True なので or 全体が True
  2. 外側の if に入る
  3. 5000 >= 3000True なので内側の if に入る
  4. return "週末の使いすぎ"

weekend_alert("月", 5000) なら 1 で False になり、外側の if を丸ごと飛ばして return "平日の支出" に落ちます。金額がいくら大きくても、内側の判定には一切たどり着きません。

よくある間違い

  1. day == "土" or "日" と書くPython はこれを (day == "土") or ("日") と読みます。"日" は空でない文字列なので常に True 扱いになり、どの曜日でも週末になってしまいます。== は省略できません。
  2. インデントを 1 段しか下げない — 内側の if の中身は 12 個分下げます。8 個のままだと外側の if 直下の処理になり、意味が変わります。
  3. andor を取り違えるand は両方、or はどちらか一方です。「週末かつ高額」は and です。

やってみよう

関数 weekend_alert(day, price) を実装してください。day"月" から "日" までの曜日 1 文字です。

day"土""日" で、かつ price3000 以上なら "週末の使いすぎ" を返します。週末だが 3000 未満なら "週末の支出"、週末でなければ金額に関係なく "平日の支出" を返します。

ネストと and の両方で書いてみて、自分にはどちらが読みやすいか確かめてみてください。

要件

  1. 関数名は weekend_alert で、引数は day と price の 2 つ
  2. day が "土" または "日" かつ price が 3000 以上なら "週末の使いすぎ" を return する
  3. 週末だが price が 3000 未満なら "週末の支出" を return する
  4. day が "土" と "日" のどちらでもなければ、金額に関係なく "平日の支出" を return する

入出力例

weekend_alert("土", 5000)"週末の使いすぎ" weekend_alert("日", 3000)"週末の使いすぎ" weekend_alert("土", 2999)"週末の支出" weekend_alert("月", 5000)"平日の支出" weekend_alert("金", 0)"平日の支出" weekend_alert("日", 0)"週末の支出"

ヒント

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

メモ

条件の組み合わせ

⌘S で保存