条件の組み合わせ
このレッスンで作るもの — 曜日と金額の 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 回書かずに済みます。
図にすると、ネスト版も and 版も通る道はまったく同じです。違うのは書き方だけで、結果は 1 文字も変わりません。
どちらが読みやすいか
答えは「場合による」ですが、目安はあります。
andが向くとき — 2 つの条件がそろったときの処理が 1 つだけ。平らに書けて分かりやすい- ネストが向くとき — 外側の条件の中に、内側で分かれる処理が複数ある
今回のように「週末のとき」の中で 2 つに分かれるなら、ネストのほうが構造をそのまま写せます。一方「週末かつ高額のときだけ警告」であれば and 一択です。
迷ったら「同じ条件を 2 回書いていないか」を見ます。書いていたらネスト、書いていなければ
andが素直です。
動きを追ってみる
weekend_alert("土", 5000) のネスト版の流れは下記のとおりです。
day == "土"がTrueなのでor全体がTrue- 外側の
ifに入る 5000 >= 3000がTrueなので内側のifに入るreturn "週末の使いすぎ"
weekend_alert("月", 5000) なら 1 で False になり、外側の if を丸ごと飛ばして return "平日の支出" に落ちます。金額がいくら大きくても、内側の判定には一切たどり着きません。
よくある間違い
day == "土" or "日"と書く —Pythonはこれを(day == "土") or ("日")と読みます。"日"は空でない文字列なので常にTrue扱いになり、どの曜日でも週末になってしまいます。==は省略できません。- インデントを 1 段しか下げない — 内側の
ifの中身は 12 個分下げます。8 個のままだと外側のif直下の処理になり、意味が変わります。 andとorを取り違える —andは両方、orはどちらか一方です。「週末かつ高額」はandです。
やってみよう
関数 weekend_alert(day, price) を実装してください。day は "月" から "日" までの曜日 1 文字です。
day が "土" か "日" で、かつ price が 3000 以上なら "週末の使いすぎ" を返します。週末だが 3000 未満なら "週末の支出"、週末でなければ金額に関係なく "平日の支出" を返します。
ネストと and の両方で書いてみて、自分にはどちらが読みやすいか確かめてみてください。
要件
- 関数名は weekend_alert で、引数は day と price の 2 つ
- day が "土" または "日" かつ price が 3000 以上なら "週末の使いすぎ" を return する
- 週末だが price が 3000 未満なら "週末の支出" を return する
- day が "土" と "日" のどちらでもなければ、金額に関係なく "平日の支出" を return する
入出力例
weekend_alert("土", 5000) → "週末の使いすぎ"
weekend_alert("日", 3000) → "週末の使いすぎ"
weekend_alert("土", 2999) → "週末の支出"
weekend_alert("月", 5000) → "平日の支出"
weekend_alert("金", 0) → "平日の支出"
weekend_alert("日", 0) → "週末の支出"