Python
ポインタ
入門
Pointer

Ptyhonとポインタの覚書

# C言語erのためのPython
# code規約の文章(PEP8とかいうやつ)はまだ読んでない。いつか読む。

C言語が染み付いている私がPythonを理解するために、壮絶に混乱したポインタ周りについてまとめてみた。

Ptyhonにおける変数は基本ポインタらしい。

だいたい変数が指しているのはポインタだと思っておけばOK。そうすれば下みたいなListにおけるshallowコピーとかも直感的に理解できる。

>>> list = [1, 2, 3, 4]
>>> id(list)
139873437253576
>>> newlist = list #あれ、これってCと同じじゃね?
>>> id(newlist)
139873437253576
>>> print(newlist)
[1, 2, 3, 4]

やった!これはCと同じ操作感。いいね!

整数の場合

あれ?ちょっとまってじゃあ整数型の代入の場合はどうなるの?

>>> a = 0
>>> b = 3
>>> print(id(a))
139804559021632
>>> print(id(b))
139804559021728
>>> b = a
>>> print(id(b))
139804559021632
>>> print(b)
0
>>> 

まじか!なんと、整数でもb=aでbに値じゃなくてaのポインタが入ってしまうのだ。

# C言語使いにとってはstringはcharのリストなのでびっくりしないよね。

整数の値変更

まってまって、じゃあ整数の変数の値を変更するとどうなるの?

>>> int = 1
>>> print(id(int))
140243712394848
>>> int += 1
>>> print(id(int))
140243712394880
>>> 

まーじーか!変数更新するたび、オブジェクト作ってるのね。これが今風ってやつ?富豪?これが富豪なの?すごいな。きっとこの古いオブジェクトはすぐに解放されるんだと思うんだけど、でもいつかメモリ使用量とか調べてみたい。

リスト要素の更新

で、じゃあリストの要素を更新するとどうなるか。
リストを作って0番目の要素を更新。

>>> list = [1, 2, 3]
>>> id(list)
140272989089736
>>> id(list[0])
140273007744608
>>> id(list[1])
140273007744640
>>> id(list[2])
140273007744672
>>> list[0] = 10
>>> list
[10, 2, 3]
>>> id(list)
140272989089736
>>> id(list[0])
140273007744896
>>> id(list[1])
140273007744640
>>> 

0番目の要素のidだけが変わってあとは変わらない感じ。上の整数の例の後だと予想通り。
だけど、C言語でのリストとメモリへの展開が全然違うことがわかる。C言語ではリストに対し連続したメモリ空間が確保されるのに対して、Pythonのリストは、メモリ上ではポインタのリストとそれに参照されたオブジェクト、もしくはLinked-list(連結リスト)ですな。

この辺はリストの操作をしてみればわかりそう。