はじめに
Pythonに限らずかと思いますが、参照には要注意です。
今回はその要注意と言う理由の一例を紹介します。
二重配列(リスト)の作り方2パターン
list1 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
sub_list = [1, 2, 3]
list2 = [sub_list, sub_list, sub_list]
これ、標準出力するとどちらも同じものが表示されます。
でも、一部の要素を更新しようとした際に違いが見えてきます。
例えば、次のコードを実行してみるとしましょう。
list1[1][2] = 5
print(list1)
list2[1][2] = 5
print(list2)
実行すると、
[[1, 2, 3], [1, 2, 5], [1, 2, 3]]
[[1, 2, 5], [1, 2, 5], [1, 2, 5]]
こうなります。
list2は他の要素まで更新されてます。
なぜそうなるのか
list2はsub_listという同じリストが3つ並べられたリストだから。
最初にlist2を初期化したときに、sub_listの値がコピーされたのではなく、sub_listの参照がコピーされたため、list2の要素を更新しようとすると大元のsub_listの中身を更新し、その結果、sub_listを何度も参照しているlist2は他の部分まで書き換わるのです。
まとめ
Pythonのリストは他の変数に代入すると値そのものではなく参照が代入されるので気をつけましょう。ちなみにリストの値そのものを代入したいときはcopy()関数を利用するそうです。
※ @shiracamus さんに指摘いただいたので記事を修正しました。