問題
a = [1, 4, 7, 11] b = list(a) a[3] =10 print(b[3])
答え
11 が出力されます。
Pythonでは、リストは代入すると同じリストを指します。
>>> a = [1, 4, 7, 11] >>> b = a >>> a is b True >>> id(a) 1927677055240 >>> id(b) 1927677055240
Pythonでのリストのコピー
コピーをするためにはいくつか方法があります。
スタックオーバーフローの以下の記事が大変良いです。
ちなみに、数ある方法の中で、スライスが一番スピードが速いようです。
10.59 sec (105.9us/itn) –
https://stackoverflow.com/a/2612990copy.deepcopy(old_list)
10.16 sec (101.6us/itn) – pure pythonCopy()
method copying classes with deepcopy
1.488 sec (14.88us/itn) – pure pythonCopy()
method not copying classes (only dicts/lists/tuples)
0.325 sec (3.25us/itn) –for item in old_list: new_list.append(item)
0.217 sec (2.17us/itn) –[i for i in old_list]
(a list comprehension)
0.186 sec (1.86us/itn) –copy.copy(old_list)
0.075 sec (0.75us/itn) –list(old_list)
0.053 sec (0.53us/itn) –new_list = []; new_list.extend(old_list)
0.039 sec (0.39us/itn) –old_list[:]
(list slicing)
copyモジュール
>>> import copy >>> a = [1, 4, 7, 11] >>> b = copy.copy(a) >>> print(b) [1, 4, 7, 11] >>> a is b False
もし 、リストの中にオブジェクトがある場合、その中のオブジェクトもコピーするためには、copy.deepcopy()を使います。この場合はdeepcopyの一択で、他の方法は使えません。
スライス
>>> a = [1, 4, 7, 11] >>> b = a[:] >>> print(b) [1, 4, 7, 11] >>> a is b False
list()
>>> a = [1, 4, 7, 11] >>> b = list(a) >>> print(b) [1, 4, 7, 11] >>> a is b False
これは、[[1, 4, 7, 11]]を返すと思っていたけど、違ったんですね。
class
https://docs.python.org/2/library/functions.html#func-listlist
([iterable])
Return a list whose items are the same and in the same order as iterable’s items. iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar toiterable[:]
. For instance,list('abc')
returns['a', 'b', 'c']
andlist( (1, 2, 3) )
returns[1, 2, 3]
. If no argument is given, returns a new empty list,[]
.
イテラブルなものが既にリストであるなら、イテラブル[:]と同じように、コピーしてそのコピーを返します。