訂正してくれた@eryksunに感謝します!
これはinterning
、Pythonのメカニズム呼び出しが原因です。
「インターンされた」文字列のテーブルに文字列を入力し、インターンされた文字列を返します。これは文字列自体またはコピーです。文字列のインターンは、ディクショナリルックアップのパフォーマンスを少し向上させるのに役立ちます。ディクショナリ内のキーがインターンされ、ルックアップキーがインターンされている場合、キー比較(ハッシュ後)は、文字列比較の代わりにポインタ比較によって実行できます。通常、Pythonプログラムで使用される名前は自動的にインターンされ、モジュール、クラス、またはインスタンスの属性を保持するために使用されるディクショナリにはインターンされたキーがあります。
バージョン2.3で変更:インターンされた文字列は不滅ではありません(Python 2.2以前のように)。恩恵を受けるには、intern()の戻り値への参照を保持する必要があります。
CPythonは、特定の文字列(1文字の文字列、キーワード、スペースが割り当てられていない文字列)を自動的にインターンして、検索速度と比較速度を向上させます'dog' is 'dog'
。たとえば、完全な文字列比較ではなく、ポインター比較になります。ただし、すべての(より長い)文字列の自動インターンには、常に実行可能とは限らないより多くのメモリが必要であるため、同じIDを共有しない場合があり、結果がid()
異なります。たとえば、次のようになります。
# different id when not assigned
In [146]: id('dog')
Out[146]: 4380547672
In [147]: id('dog')
Out[147]: 4380547552
# if assigned, the strings will be interned (though depends on implementation)
In [148]: a = 'dog'
In [149]: b = 'dog'
In [150]: id(a)
Out[150]: 4380547352
In [151]: id(b)
Out[151]: 4380547352
In [152]: a is b
Out[152]: True
整数の場合、少なくとも私のマシンでは、CPythonは自動的に最大256を自動的にインターンします。
In [18]: id(256)
Out[18]: 140511109257408
In [19]: id(256)
Out[19]: 140511109257408
In [20]: id(257)
Out[20]: 140511112156576
In [21]: id(257)
Out[21]: 140511110188504
@eryksunのおかげで更新:この場合、CPythonはスペースのない文字列のみをインターンする'a string'
ため、文字列はインターンされません。たとえば、ASCII文字、数字、アンダースコアなど、私が即座に想定した長さのためではありません。
詳細については、こちらのAlexMartelliの回答を参照することもできます。