連鎖比較と優先順位

このレッスンで作るもの — 0 <= price <= budget のように比較を連ねる書き方と、演算子が計算される順番を整理します。

連鎖比較と優先順位

「金額が 0 円以上、かつ予算以下」を判定したいとします。前回までの道具で書くと下記のようになります。

price >= 0 and price <= budget

間違いではありません。ただ Python には、これを数学の式そのままの見た目で書ける記法があります。

0 <= price <= budget

これを 連鎖比較 と呼びます。多くのプログラミング言語では書けない、Python の気持ちのよいところです。

数学で 0 ≦ x ≦ 10 と書くのと同じ形がそのまま通ります。読み手にとって意味が一瞬で分かるので、範囲の判定はこの形を優先します。

連鎖比較の中身

0 <= price <= budget は、内部的には 0 <= price and price <= budget と同じ意味に展開されます。つまり 両方の条件を満たしたときだけ True です。

price = 500 budget = 3000 print(0 <= price <= budget) # True price = 5000 print(0 <= price <= budget) # False

and に展開されるので、真ん中の price は 1 回しか評価されません。関数呼び出しを真ん中に置いても二重に呼ばれない、という利点もあります。

3 つ以上つなぐこともできます。0 <= a <= b <= 100 のような書き方も通りますが、長くなるほど読みにくくなるので、2 段までにとどめるのが実用的です。

演算子の優先順位

式の中に複数の演算子が混ざったとき、どれから計算されるかは決まっています。強い順に並べると下記のとおりです。

  1. かっこ ()
  2. 掛け算・割り算 * / // %
  3. 足し算・引き算 + -
  4. 比較 < <= > >= == != in not in
  5. not
  6. and
  7. or

算数の演算が先、次に比較、最後に論理演算という 3 段構えです。この順番のおかげで、下記の式はかっこなしで期待どおりに動きます。

total = 1200 budget = 3000 print(total * 2 > budget and total > 0) # True

total * 22400 が先に出て、2400 > 3000Falsetotal > 0TrueFalse and TrueFalse。落ち着いて上から段を降りれば読めます。

diagram (will load when visible)

迷ったらかっこ

優先順位は覚えるに越したことはありませんが、実務では 迷ったらかっこを付ける のが正解です。かっこは実行速度をほとんど変えず、読み手の負担だけを減らします。

# 動きは同じだが、意図がはっきりする (total > budget) or ((total > 0) and (category == "食費"))

とくに andor が混ざるときは要注意です。and のほうが強いので、A or B and CA or (B and C) になります。(A or B) and C のつもりで書くと結果が変わります。

「動くから正しい」と「読めるから正しい」は別の話です。3 か月後の自分が読める式を書いてください。

動きを追ってみる

in_range(500, 3000) の流れを追います。

  1. price500budget3000 が入る
  2. 0 <= price を評価して True になる
  3. price <= budget を評価して True になる
  4. 両方 True なので全体が True になり、それが返る

in_range(-100, 3000) なら、1 つ目の 0 <= -100False になった時点で打ち切られ、False が返ります。マイナスの金額を弾けるので、入力チェックとして使えます。

よくある間違い

  1. 不等号の向きをそろえない0 <= price >= budget と書くと、意味の分からない条件になります。範囲を表すときは向きをそろえます。
  2. andor の強さを逆に覚えるand のほうが強く、先にまとまります。混ぜるときはかっこを付けます。
  3. 0 <= price <= budget0 <= price and <= budget と書くand の右側にも完全な条件が必要です。この形は SyntaxError になります。

やってみよう

関数 in_range(price, budget) を実装してください。price0 以上かつ budget 以下のとき True、そうでないとき False を返します。

return 0 <= price <= budget の 1 行で書けます。and を使った形でも正解ですが、まずは連鎖比較の書き味を試してみてください。price がちょうど 0 のときも、ちょうど budget と同じときも、どちらも範囲に含まれて True になります。

要件

  1. 関数名は in_range で、引数は price と budget の2つ
  2. price が 0 以上かつ budget 以下のとき True を返す
  3. 下限の 0 と上限の budget はどちらも範囲に含める
  4. 0 <= price <= budget の連鎖比較で書く(and を使った形でも可)

入出力例

in_range(500, 3000)true in_range(0, 3000)true in_range(3000, 3000)true in_range(3001, 3000)false in_range(-100, 3000)false in_range(0, 0)true

ヒント

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

メモ

連鎖比較と優先順位

⌘S で保存