Pythonのisは小さい整数と大きい整数で違う?

同じ整数を書けば、isの結果も同じなのか

Pythonで同じ値の整数を別々の名前に代入したとき、その二つをisで比べた結果は、値が等しいことだけで決められるのでしょうか。公式ドキュメントの「Literals and object identity」には、小さい整数と大きい整数で異なる結果になるCPythonの例が載っています。

ただし、この例を「整数の大小によって、Pythonの仕様として結果が決まる」と読むことはできません。説明には「CPython implementation detail」という区別があり、さらに将来の版で挙動が変わる可能性も明記されています。

ここで確かめたいのは、小さい整数と大きい整数のどちらでisが成立するか、という例の違いだけではありません。その違いが、どこまで保証されたものなのかが問題です。同じ値を記述したことと、同じオブジェクトを得たことを分けて読む必要があります。

公式は同じ値と同じオブジェクトを分けている

公式ドキュメントは、同じ値のリテラルを複数回評価した場合について、次のように記述しています。

Multiple evaluations of literals with the same value (either the same occurrence in the program text or a different occurrence) may obtain the same object or a different object with the same value.

出典: https://docs.python.org/3/reference/expressions.html#is (取得日 2026-10-16)

同じ値のリテラルであっても、同じオブジェクトを得る場合と、同じ値を持つ別のオブジェクトを得る場合がある、という規定です。プログラム中の同じ記述を複数回評価する場合も、異なる場所に書いた記述を評価する場合も、この説明に含まれています。

その直前では、すべてのリテラルが不変のデータ型に対応し、オブジェクトの同一性よりも値のほうが重要だと説明されています。したがって、同じ整数を二度書いたという情報だけから、二度の評価が同じオブジェクトを返すと判断することはできません。

続くCPython固有の説明には、次のコードが掲載されています。ここでは素材中の入力部分だけをそのまま引用します。

>>> x = 7
>>> y = 7
>>> x is y

公式の例では、この小さい整数について同じオブジェクトになることが示されています。一方、大きい整数の例として登場する123456789については、異なるオブジェクトになると説明されています。これらは公式に掲載された例の説明であり、ここで実行して得た結果ではありません。

小さい整数と大きい整数を比べる

公式の例と、その例を利用するときの制約を並べると、次のようになります。

比べる対象 公式に掲載された値 CPythonの例での説明 適用範囲についての注意
小さい整数 7 同じ値の評価で同じオブジェクトになる 実装の詳細であり、将来変わる可能性がある
大きい整数 123456789 異なるオブジェクトになる 実装の詳細であり、将来変わる可能性がある

この表で注意したいのは、二つの値の間に境界を補っていない点です。提示された公式本文には、小さい整数と大きい整数を分ける具体的な範囲は書かれていません。書かれているのは、その境界が過去に変更されたという説明です。

そのため、7の例から「ここまでの整数は同じオブジェクトになる」と範囲を広げたり、123456789の例から「この大きさ以上なら必ず別のオブジェクトになる」と決めたりする根拠はありません。個別の例と、値の範囲に対する保証は分けて扱う必要があります。

また、リテラル全般の規定には「同じオブジェクトでも、同じ値の別オブジェクトでもよい」という余地があります。CPythonの例を読むときも、この一般の規定と実装固有の説明を一つの保証にまとめないことが大切です。

値を比べたいときの選択と落とし穴

整数の値を比べるためにisを使おうとしているなら、公式にある警告の案内を確認できます。本文は、CPythonがリテラルをisで比較するとSyntaxWarningを出すと説明し、警告文で==を使う意図ではないかと問いかけています。

この案内から、値を比べたいコードでは==を検討する、という選び方ができます。少なくとも、小さい整数の例で同じオブジェクトになったことを理由に、整数の値の比較へisを採用する読み方は避けたいところです。同じ値から同じオブジェクトを得ることは、リテラル全般の規定では保証されていません。

警告についても、説明されている条件を広げないようにします。素材が明記しているのは、リテラルをisで比較する場合です。名前同士を比較する式も含め、すべての不適切な比較に警告が出るとは書かれていません。警告の有無だけを、比較の目的に合っているかどうかの判断材料にはできません。

同じ注意は整数以外にも関係します。タプルについても、同じ値を持つ二つの記述が同じオブジェクトを生むかどうかは決まらず、リテラルの同一性の規則が適用されると説明されています。整数の大小だけを覚えるより、値の一致からオブジェクトの同一性を決めつけないことが、本文の規定に沿った読み方です。

自分の環境で確かめる手順

Pythonの対話環境を起動し、公式の例にある小さい整数と大きい整数について、次の入力を一行ずつ実行してください。比較対象の値とisの判定を並べて確認するための手順です。実行結果はここには掲載しません。

x = 7
y = 7
print(x, y, x is y)
x = 123456789; y = 123456789
print(x, y, x is y)

確認できるのは、その実行環境と入力方法での挙動です。結果が公式の例と一致した場合も、それだけで小さい整数の範囲や将来の版での挙動まで確定することはできません。観察した結果は、その環境での確認として扱い、コードの判断条件には公式が保証している範囲を使ってください。

コメント

タイトルとURLをコピーしました