LoginSignup
14
14

More than 5 years have passed since last update.

Python で is と == の使いドコロを迷う人のためのTips

Last updated at Posted at 2017-07-12

is はオブジェクトの比較で使うべし

Pythonでは、 if x is yif x == y と書くことがあります。
その際に、is==で迷ってしまう場合があります。
そこで、is==の違いを以下にまとめました。

  • isはオブジェクトの比較を行う(同一のオブジェクトかどうか)
  • ==は値の比較を行う(同一の値かどうか)

※厳密には、オブジェクトの比較ではなく、「オブジェクトのIDの比較」であり、(結果的には)「アドレスの比較」となります。脚注1,2

ユースケース(isを使う場合)

x = <object A>
を定義していて、
if x is <object A>:
という条件式を書きたい場合が該当します。

もちろん、True/False比較のために
x = True
を定義して、
if x is True:
と書くことは、間違いではありませんが、この場合に関してはpythonic的に
if x:
と書くのが良いです。

→なぜ、 x is Trueでも問題ないかというと、boolクラスのTrue/Falseは、常にひとつだけしか存在しないように設計されているためです。

The values False and True will be singletons, like None.

引用元
PEP285

ユースケース(==を使う場合)

x = 1234
を定義していて、
if x == 1234:
という条件式を書きたい場合が該当します。

まとめ

is と == を混同せずに、しっかりと使い分けましょう。

脚注

脚注1
@7of9 さんよりコメント欄でご提示頂いた内容

https://docs.python.org/3.6/library/functions.html#id

id(object)
...
CPython implementation detail: This is the address of the object in memory.

がドキュメントで根拠となる部分です。

脚注2
@shiracamus さんよりコメント欄でご提示頂いた内容

CPythonのソースを調べてみました。
"is" は Is に置き換えられ、Is は PyCmp_IS に置き換えられ、PyCmp_IS は以下のようにアドレスを比較してました。

Python/ceval.c
static PyObject *
cmp_outcome(int op, register PyObject *v, register PyObject *w)
{
    int res = 0;
    switch (op) {
    case PyCmp_IS:
        res = (v == w);
        break;
    case PyCmp_IS_NOT:
        res = (v != w);
        break;

のように、最終的にはアドレス比較を行っています。

14
14
9

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
14
14