1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

python3: difference between "is" and "==", unexpected behavior with integers

Last updated at Posted at 2016-03-02

今日は==isの違いについてざっくりと。言葉で説明するよりまずは具体例を見せたほうが早いと思ったので以下を参照に。

>>> lst1 = [1,2,3]
>>> lst2 = [1,2,3]
>>> lst1 == lst2
True
>>> lst1 is lst2
False
>>> lst1 = lst2
>>> lst1 is lst2
True

isと==の違い

簡単に言うと==は"value equality"(簡単にいえばぱっと見中身が同じかどうか)を確かめる。isは各オブジェクトのポインターの方向を示している。一言で言えば"reference equality"実際にpythontutor.comで各オブジェクトの動きを見ると分かりやすいかもしれない。他の言語については分からないが(たしかCは同じだったと聞いた)少なくともpythonの世界ではlst1lst2は中身は同じでも違うオブジェクトとして認識される。そのためis判定を行うとFalseと出る。極端な説明をすればlst1lst2は各リストの出身地と考えてみてもいいかもしれない。

簡潔に言うと:

use == if you mean the objects should represent the same thing (most common usage) and is if you mean the objects should be in identical pieces of memory (you'd know if you needed the latter).

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True
>>> b = a[:] # b(=a[:])とa([1,2,3])はis判定ではfalse
>>> b is a
False
>>> b == a
True

SOFを参考にこの考え方を少しだけ広げてみる。intでもこれは通じる:

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True

そしてstrでも同じことが言える:

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

中でも特に興味深かったのがクラスを用いて比較した例:

>>> class foo(object):
       def __eq__(self, other):
           return True

>>> f = foo()
>>> f == None
True
>>> f is None
False
>>> f = None
>>> f is None
True

読んでみて「たしかに!」と気付かされました。一度感覚をつかめばちょっとした応用にも使えそう。

isを使ってintを比較する際の注意点

どうやらintに対してはisは少し奇妙な振る舞いをするらしい。

>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False

>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True

を比較すると分かるかもしれないが、数に応じてpythonとやらが変わった振る舞いを行う用にできているらしい。これはpythonがintの-5から256までしかreference implementation(=is)に対応していないからだという。これがpythonのパフォーマンス向上の理由の一つなんだとか。

>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
... 
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False

よってisを用いてintを扱うときは注意したほうが良さそうだ。ちなみにこれはid(int)でも調べることが可能。

参考にしたリンク

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?