BlankTar

about | blog | works | photo

pythonのif文とかで使うのにisとか==とかあるじゃないっすか。
あれはどういう違いがあるのか、というお話。

is

pythonのオブジェクトにはIDっちゅうのがあります。

>>> a = 1
>>> id(a)

みたいにすると見れる。CPythonの実装だとメモリアドレスらしいね。
オブジェクトを一意に識別するためのアイデンティティ、とのこと。

で、このIDが等しいかどうかを比較するのがisってやつ。
つまりは同じ実体かどうか、ってのを調べるのがisの役割、かな。

同じ数値は同じIDを持つ(環境依存だったらごめん)ので、

>>> a = 1
>>> b = 1
>>> id(a) - id(b) is 0
True
>>> a is b
True

となります。

でも、リストなんかは常に別のIDになるので、

>>> a = []
>>> b = []
>>> id(a) - id(b) is 0
False
>>> a is b
False
>>> [1, 2, 3] is [1, 2, 3]
False

てな感じ。ちょっと直感的じゃないよね。

==

さて、今度は==ってやつ。
==の左辺のオブジェクトの__cmp__関数に右辺のオブジェクトを渡して、戻り値が0ならTrueになる。
まあ、手っ取り早く言えばオブジェクトが持ってる値自体を比較するものです。

>>> class test(int):
... 	def __cmp__(self, arg):
... 		ret = int.__cmp__(self, arg)
... 		print 'cmp: {0}, {1} => {2}'.format(self, arg, ret)
... 		return ret
... 
>>> test(1) == test(1)
cmp: 1, 1 => 0
True
>>> test(1) == test(2)
cmp: 1, 2 => -1
False

みたいになります。

これを使えば、リストの比較でも

>>> a = []
>>> b = []
>>> a == b
True
>>> [1, 2, 3] == [1, 2, 3]
True
>>> [1, 2, 3] == [1, 3, 2]
False

こんな感じで直感的な結果に。

似ているようでぜんぜん違う。ちょっと分かりづらいね・・・。

参考: 式 (expression) - Python 2.7ja1 documentation

keyword: >>> == is True __cmp__ cmp
< pythonのジェネレータをリスト内包表記的に書く zfsの重複排除で未来を感じてみる >