3.

Python の演算子完全ガイド|算術・比較・論理・ビットと is / in の使い分け

編集
この記事の要点
  • Python の演算子は算術・比較・論理・代入・ビット・メンバーシップ・同一性の 7 系統
  • Python 特有の点: / は常に float// が整数除算。and / orbool ではなくオペランドそのものを返す
  • 連鎖比較 0 <= x < 10 が書ける(他言語には無い書き方)
  • == は値の比較、is同一オブジェクトかの比較。None の判定は is None
  • 演算子はクラス側で __add__ などの特殊メソッドを定義すると振る舞いを変えられる

Python の演算子一覧

Python の演算子は次の 7 系統に分けて覚えると整理しやすくなります。各系統の詳細は子記事にまとめています。

系統演算子詳細
算術+ - * / // % **算術演算子
文字列+(連結)*(反復)文字列演算子
代入= と複合代入、:=代入演算子
比較== != < <= > >=比較演算子
論理and or not論理演算子
ビット& | ^ ~ << >>ビット演算子
メンバーシップ / 同一性in / not inis / is notこの記事の後半

他の言語から来た人がつまずく 3 点

1. / は必ず float を返す

Python 3 では、整数どうしの割り算でも結果は float になります。整数で欲しいときは // を使います。

print(7 / 2)    # 3.5   ← int どうしでも float
print(7 // 2)   # 3     ← 切り捨て除算
print(7 % 2)    # 1
print(2 ** 10)  # 1024  ← べき乗は ** (^ ではない)

^ はべき乗ではなくビット XOR です。2 ^ 10 は 8 になります。

2. and / or は bool を返さない

短絡評価で「評価を打ち切った側のオペランド」がそのまま返ります。

print(0 or "default")     # default   ← 0 が偽なので右側
print("a" or "b")         # a         ← 左が真なら左を返す
print(1 and 2)            # 2
print(bool(1 and 2))      # True      ← bool が欲しいなら明示的に

3. 比較は連鎖できる

x = 5
print(0 <= x < 10)        # True  ← (0 <= x) and (x < 10) と同じ
print(1 < 2 < 3 < 4)     # True

メンバーシップ演算子(in / not in)

print("py" in "python")          # True   文字列は部分一致
print(3 in [1, 2, 3])            # True
print("k" in {"k": 1})           # True   辞書はキーを見る
print(5 not in {1, 2, 3})        # True

listin は先頭から線形探索するため、要素数が多いなら setdict にすると平均 O(1) になります。

同一性演算子(is / is not)

==値が等しいかを見るのに対し、is同じオブジェクトかを見ます。

a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)   # True   中身は同じ
print(a is b)   # False  別オブジェクト

x = None
print(x is None)      # True   ← None の判定はこれが正しい
print(x == None)      # True だが非推奨(__eq__ を上書きされると壊れる)

小さい整数や短い文字列は処理系がキャッシュしているため is が偶然 True になることがあります。値の比較に is を使ってはいけません。

優先順位

強い順に、おおまかに次のとおりです。迷ったら括弧を付けるのが確実です。

優先度演算子
**
 +x -x ~x(単項)
 * / // %
 + -
 << >>&^|
 比較 / in / is
 notandor
if - else(条件式)、lambda

** だけは右結合です。2 ** 3 ** 22 ** (3 ** 2) = 512 になります。

演算子は自分のクラスでも定義できる

class Vec:
    def __init__(self, x, y):
        self.x, self.y = x, y
    def __add__(self, other):          # + の振る舞い
        return Vec(self.x + other.x, self.y + other.y)
    def __eq__(self, other):           # == の振る舞い
        return (self.x, self.y) == (other.x, other.y)
    def __repr__(self):
        return f"Vec({self.x}, {self.y})"

print(Vec(1, 2) + Vec(3, 4))   # Vec(4, 6)

関連

編集
Post Share
子ページ
  1. 算術演算子
  2. 文字列演算子
  3. 代入演算子
  4. 比較演算子
  5. 論理演算子
  6. ビット演算子
同階層のページ
  1. 基本的なルール
  2. 変数
  3. 演算子
  4. 標準ライブラリ
  5. 外部ライブラリ
  6. 制御構文
  7. リスト(配列)
  8. タプル
  9. セット
  10. 辞書(dict)
  11. クラスとメソッド
  12. 継承の概念と必要性
  13. 継承の構文
  14. コンストラクタ
  15. cookieの値の設定と取得
  16. 例外処理
  17. 例外を文字列で出力する方法
  18. httpリクエスト(curl)をする方法
  19. Responseオブジェクトの中身の確認
  20. 変数が空かどうか判定する方法
  21. タイムゾーンの設定と現在日時の取得と文字列化
  22. シングルクォーテーションとダブルクォーテーションの違い

最近更新/作成されたページ