Python簡単実験:*による繰り返しは本当に繰り返しか?


2016年 12月 03日

とても簡単なリストの実験をしてみよう。
リストで繰り返しがあるとき、*で済ませると楽ができる。 とても簡単な例。
In [54]: A = [1,2,1,2,1,2]

In [55]: B = [1,2]*3

In [56]: print(A,B)
[1, 2, 1, 2, 1, 2] [1, 2, 1, 2, 1, 2]

In [57]: A==B
Out[57]: True

In [58]: A[3]+=5

In [59]: B[3]+=5

In [60]: print(A,B)
[1, 2, 1, 7, 1, 2] [1, 2, 1, 7, 1, 2]

In [61]: A==B
Out[61]: True
リストA,Bは当然同じ動きをする。 では、リストの要素を数字ではなく、リストに変えてみよう。 つまり、リストのリストの場合、どうなるだろうか?
In [80]: A = [[],[],[],[],[],[]]

In [81]: B = [[]]*6

In [82]: print(A); print(B); print(A==B)
[[], [], [], [], [], []]
[[], [], [], [], [], []]
True

In [83]: A[3].append(1)

In [84]: B[3].append(1)

In [85]: print(A); print(B); print(A==B)
[[], [], [], [1], [], []]
[[1], [1], [1], [1], [1], [1]]
False
リストAとBを2つの方法で作り、一致していることを確認した。 次に、A[3]とB[3]に1をappendした。 AとBは同じで、同じ操作をしたのだから、結果も同じになるはずなのだが、なっていない。
*6 により[]を6個にしても、実体は1つのままのようだ。

このでは、[]で実験したが、オブジェクトだったら全て同様の結果になるであろう。
オブジェクトを指している変数を、別の変数に代入しても同じオブジェクトを指すようになるだけというのが良く説明されているが、こういう場合にも同じ現象が当然起きる。

実験では、[]が6個だから、全部書いてもたいしたことはない。
もし、[]が100個だったら、n個だったらどうすればオブジェクトとして別々の[]を指定個数並べられるのだろうか?