copy(リスト、配列)
このページでは豊富な例を用いてPythonの リストクラス のcopyメソッドの使い方を学ぶことができます。
copyメソッドは リストクラス(list) のメソッドの1つで、呼び出し元のリストをコピーした新たなリストを戻り値として返します。
このメソッドでのコピーは浅いコピー(shallow copy)です。
コピーされたリストを操作する際は、コピー元のリストへの影響に注意してください。(逆もしかりです。)
TL;DR
基本
list1 = [1, 2, 3, 4, 5]
copied_list1 = list1.copy()
print(copied_list1)
==> [1, 2, 3, 4, 5]
print(list1)
==> [1, 2, 3, 4, 5]
# それぞれのリストの識別値は異なる
print(id(list1) == id(copied_list1))
==> False
list2 = ['Python', 'JavaScript', 'TypeScript']
copied_list2 = list2.copy()
print(copied_list2)
==> ['Python', 'JavaScript', 'TypeScript']
list3 = [True, False]
copied_list3 = list3.copy()
print(copied_list3)
==> [True, False]
浅いコピーの注意点
複合オブジェクト(compound object):
リストや辞書(dict)のように、他のオブジェクトを要素に含むオブジェクト
list1 = [100, 200, 300]
copied_list1 = list1.copy()
print(copied_list1)
==> [100, 200, 300]
# コピーされたリストを変更する
copied_list1[0] = 999
# 「変更された要素が複合オブジェクトではない」のでコピー元には影響がない
print(copied_list1)
==> [999, 200, 300]
print(list1)
==> [100, 200, 300]
# 「複合オブジェクトの要素」を変更する場合
list2 = [{'id': 1}, {'id': 2}]
copied_list2 = list2.copy()
print(copied_list2)
==> [{'id': 1}, {'id': 2}]
# 辞書の特定キーのバリューを変更する
copied_list2[0]['id'] = 100
# 「複合オブジェクトの要素」を変更したのでコピー元に影響が出る
print(copied_list2)
==> [{'id': 100}, {'id': 2}]
print(list2)
==> [{'id': 100}, {'id': 2}]
# 「複合オブジェクト自体」を変更した場合
list2 = [{'id': 1}, {'id': 2}]
copied_list3 = list2.copy()
copied_list3[0] = {'id': 100}
# 「複合オブジェクト自体」を変更しているのでコピー元への影響はない
print(copied_list3)
==> [{'id': 100}, {'id': 2}]
print(list2)
==> [{'id': 1}, {'id': 2}]
# リストの場合
list3 = [[0, 1], [2], [3, 4, 5]]
copied_list4 = list3.copy()
copied_list4[0][0] = 999
# 「複合オブジェクトの要素」を変更したのでコピー元に影響が出る
print(copied_list4)
==> [[999, 1], [2], [3, 4, 5]]
print(list3)
==> [[999, 1], [2], [3, 4, 5]]
# クラスの場合
class Person:
def __init__(self, name):
self.name = name
def __repr__(self):
return repr(vars(self))
list4 = [Person('Adah'), Person('Amoli')]
print(list4)
==> [{'name': 'Adah'}, {'name': 'Amoli'}]
# コピーへの影響の違い
copied_list5 = list4.copy()
list4[0] = Person('Alex')
list4[1].name = 'Ayaan'
print(copied_list5)
==> [{'name': 'Adah'}, {'name': 'Ayaan'}]
print(list4)
==> [{'name': 'Alex'}, {'name': 'Ayaan'}]
関連情報:class(クラス定義)の使用方法
解説
基本
copyメソッドは呼び出し元のリストをコピーし、そのコピーしたリストを戻り値として返します。
リストクラスのcopyメソッドの戻り値は、呼び出し元のオブジェクトの浅いコピー(shallow copy)です。
浅いコピーの注意点は次項を参照してください。
list1 = ['py', 'js', 'java']
copied_list1 = list1.copy()
print(copied_list1)
==> ['py', 'js', 'java']
print(list1)
==> ['py', 'js', 'java']
# 識別値を比較する
print(id(list1) == id(copied_list1))
==> False
浅いコピーの注意点
copyメソッドは呼び出し元のリストに対して、浅いコピーをした新たなリストを戻り値として返します。
そのため、戻り値のリストの要素に複合オブジェクトがある場合、その複合オブジェクトはコピーされず、元の複合オブジェクトに対する参照となります。
(複合オブジェクトとは、オブジェクトの要素に別のオブジェクトを含むものを指します。
代表的なものとして、リスト、辞書、独自定義クラスのインスタンスなどが挙げられます。)
コピーされたリストに複合オブジェクトが含まれており、かつ、その複合オブジェクトの要素を変更する場合は参照元の複合オブジェクトの値も変更されます。 逆もしかりで、元のリストの複合オブジェクトの要素を変更する場合には、コピーされたリストの複合オブジェクトの要素値も変更されます。
その点を十分に考慮してオブジェクト操作を行ってください。
list1 = ['python', 'javascript']
copied_list1 = list1.copy()
copied_list1[0] = 'FooBarNinja'
# 変更された要素が複合オブジェクトではないのでコピー元には影響がない
print(copied_list1)
==> ['FooBarNinja', 'javascript']
print(list1)
==> ['python', 'javascript']
# 「複合オブジェクトの要素」を変更する場合
list2 = [{'name': 'John'}, {'name': 'Ellie'}]
copied_list2 = list2.copy()
copied_list2[0]['name'] = 'Isabella'
# 「複合オブジェクトの要素」を変更したのでコピー元に影響が出る
print(copied_list2)
==> [{'name': 'Isabella'}, {'name': 'Ellie'}]
print(list2)
==> [{'name': 'Isabella'}, {'name': 'Ellie'}]
# 「複合オブジェクト自体」を変更した場合
list2 = [{'name': 'John'}, {'name': 'Ellie'}]
copied_list3 = list2.copy()
copied_list3[0] = {'name': 'Isabella'}
# 「複合オブジェクト自体」を変更しているのでコピー元への影響はない
print(copied_list3)
==> [{'name': 'Isabella'}, {'name': 'Ellie'}]
print(list2)
==> [{'name': 'John'}, {'name': 'Ellie'}]