🥺

Python で数値を比較するときは is を使ってはいけない

2022/07/13に公開

事の発端

https://twitter.com/kumassy_/status/1546496776282456067

筆者は Python の is== の使い分けをよく理解していなかったので、 AtCoder の問題を解くときに以下のようなコードを書きました

S = input()
T = input()

a = len(S)
b = len(T)

if a is b:
  print("Yes")
else:
  print("Ok")

これは ab が小さいときには想定通りに動作します。
しかし ab が大きい場合は想定通りに動作しないため、誤答となってしまいました。

is== の違い

is はオブジェクトが同一であるかを比較するのに対し、 == はオブジェクトの値が等しいかを調べます。
Python では id 関数を用いることでオブジェクトを識別できる ID を調べることができます。 is はこのオブジェクト ID が同じ値かどうかを比較します。

print(id(1)) # 4378749232

以下のコードでは ab が指している数値 12345 は同じ値ですが、オブジェクト ID が異なるため a is bFalse となってしまいます

a = 12345
b = 12345
print(id(a), id(b)) # 4380775824 4380775664
print(a is b) # False

ただし、 ab-5 から 256 の範囲の整数の場合は[1]、実装上の都合によってオブジェクト ID が同一になるため a is bTrue になります

a = 3
b = 3
print(id(a), id(b)) # 4378749296 4378749296
print(a is b) # True

is の使い所

ある変数が None かどうか調べたいときは is を使いましょう。 None はただ一つしか存在しないオブジェクトで、 オブジェクト ID は常に一定です。

a = 3

if a is None:
  print("a is None")

結論

  • Python で数値比較をするときは常に == を使う
  • Python ムズカシイ

参考リンク

脚注
  1. 実装依存です。https://stackoverflow.com/questions/2239737/is-it-better-to-use-is-or-for-number-comparison-in-python も参考にしてください ↩︎

Discussion