リストのコピー
前回、Pythonのリストの順番を並び替えるsort、sorted(ソート)、そしてreverse、reversed(逆順)の違いを解説しました。
今回はPythonのリストをコピーする際に注意することを解説していきます。
それでは始めていきましょう。
リストのおさらい
まずリストのおさらいをしていきます。
新規にリストを作成するには「リスト名 = [要素1、要素2、…]」でした。
そして要素を取り出すには、インデックス(要素の番号)を使い、「リスト名[インデックス]」で取り出すことができます。
a = [0, 1, 2, 3, 4, 5]
print(a)
print(a[2])
実行結果
[0, 1, 2, 3, 4, 5]
2
リスト内の要素を変更するには「リスト名[変更するインデックス] = 要素」です。
a = [0, 1, 2, 3, 4, 5]
a[2] = 6
print(a)
実行結果
[0, 1, 6, 3, 4, 5]
ダメなリストのコピー
それではリストのコピーを見ていきましょう。
まずはこれではダメなリストのコピー方法です。
リストを作成後、「新しいリスト名=コピー元のリスト名」としてリストをコピーしようとする方法です。
a = [0, 1, 2, 3, 4, 5]
b = a
print(a)
print(b)
実行結果
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5]
一見、普通にコピーできているように見えます。
ここでコピー元のリスト、コピー先のリストで要素の変更をしてみましょう。
コピー元のリスト「a」のインデックス「2」を「7」に、コピー先のリスト「b」のインデックス「3」を「8」に変更してみます。
a = [0, 1, 2, 3, 4, 5]
b = a
a[2] = 7
b[3] = 8
print(a)
print(b)
実行結果
[0, 1, 7, 8, 4, 5]
[0, 1, 7, 8, 4, 5]
それぞれ別々に変更したつもりが、両方のリストに両方の値(7、8)が追加されてしまっています。
もちろんそのつもりで変更したならいいのですが、コピーする場合、別のリストとして使いたくてコピーすることが多いでしょう。
その方法を次に見ていきましょう。
リストのコピー:.copy()と.deepcopy()
リストをコピーして、別のリストとして使用したい場合は「リスト名.copy()」としてコピーします。
a = [0, 1, 2, 3, 4, 5]
b = a.copy()
a[2] = 7
b[3] = 8
print(a)
print(b)
実行結果
[0, 1, 7, 3, 4, 5]
[0, 1, 2, 8, 4, 5]
ただし2次元リストのように多次元リストの場合は「リスト名.copy()」では2次元目以降の要素の変更ではうまくいきません。
例えば「リスト名.copy()」でリストをコピーした後、1次元目の要素を変更してみます。
a = [[0, 1, 2], [3, 4, 5]]
b = a.copy()
b[0] = [6, 7, 8]
print(a)
print(b)
実行結果
[[0, 1, 2], [3, 4, 5]]
[[6, 7, 8], [3, 4, 5]]
リスト「b」では、リスト「a」のインデックス[0]の要素が[6, 7, 8]に変更できています。
次に2次元目の要素としてインデックス[0][1]の要素を変更してみます。
a = [[0, 1, 2], [3, 4, 5]]
b = a.copy()
b[0][1] = 6
print(a)
print(b)
実行結果
[[0, 6, 2], [3, 4, 5]]
[[0, 6, 2], [3, 4, 5]]
この場合、コピー先のリストのインデックス[0][1]だけ変更したつもりが、コピー元のリスト、コピー先のリストの両方でインデックス[0][1]の値が変更されてしまいました。
そのため多次元リストをコピーする場合は「リスト.deepcopy()」を使います。
import copy
a = [[0, 1, 2], [3, 4, 5]]
b = copy.deepcopy(a)
b[0][1] = 6
print(a)
print(b)
実行結果
[[0, 1, 2], [3, 4, 5]]
[[0, 6, 2], [3, 4, 5]]
これによりコピー先のインデックス[0][1]だけ変更することができました。
次回はdatetimeモジュールで曜日を扱う方法を解説していきます。
ではでは今回はこんな感じで。
コメント