Python簡単実験:同じ数が別のオブジェクトになる


2016年 12月 15日

前回の実験で、同じ数字が別オブジェクトになるとしか考えられない実行結果が得られた。
今回は、それをきちんと確認しよう。
>>> a=123
>>> b=a
>>> c=123
>>> print(id(a),id(b),id(c))
140552436779360 140552436779360 140552436779360

数値のIDを調べるのに、一々変数に入れているが、これが重要なのだが、それについては後で説明する。 123をaとcに代入している。さらに、aをbに代入しているのだが、123の場合、a,b,c のIDは全て同じになっている。 次に、もうちょっと大きな数字として、12345で実験してみた。
>>> a=12345
>>> b=a
>>> c=12345
>>> print(id(a),id(b),id(c))
140552437718544 140552437718544 140552438458512
aとbはちゃんと同じIDになっているのだが、cのIDは異なる。 つまり、a, bの指すオブジェクト12345と、cのオブジェクト12345は異なっている。 これはどう考えれば良いだろうか? 小さい数の場合は、同じ整数値なら同じ整数値オブジェクトになるが、大きな値は違うようだ。 これをきちんと確認してみるために、次のプログラムを実行してみた。
>>> a = [i for i in range(100000)]
>>> b = [i for i in range(100000)]
>>> for i in range(100000):
...     if id(a[i])!=id(b[i]):
...         print(i, id(a[i]), id(b[i]))
...         break
...
257 140552437718480 140552398636944
どうやら、256までは同じ整数オブジェクトで、257以上の場合、別の整数オブジェクトが生成されてしまうようだ。 これが、メモリを食っていた原因のようだ。

実数の場合にどうなるかを試してみた。
>>> a=1.0
>>> b=a
>>> c=1.0
>>> print(id(a),id(b),id(c))
140552438575488 140552438575488 140552438575512
実数の場合、1.0でも異なる実数オブジェクトが確保されるようだ。 ということは、実数データが大量にあると、すべて別オブジェクトになってしまうので、メモリを食い潰す可能性があるので要注意だ。 さて、最後に、変数に代入してからIDを調べていたが、もし変数に代入しないでIDを求めるとどうなるか試してみた。
>>> id(1234567890)
140552438458512
>>> id(123456789)
140552438458512
>>> id(1234567)
140552438458512
>>> id(123456)
140552438458512
数値が異なるのに、今度はIDが全部同じになっている。
なぜ?
説明は省略するので、自分で考えよう。