Thursday, March 13, 2008

pythonメモ:リストのコピー

こういうのってどうなってるのかね。どっかに書いてあるのかな。
リストをコピーして加工するつもりで、元のものを保存しておきたいとする。もとをlと呼び、保存したのをrと呼ぼう。しかしr=lではコピーできていないね。参照だけがコピーされていて、中身は一つになっている。lを変更するとrも変更されてるもんね。

$ python
Python 2.5 (r25:51918, Sep 19 2006, 08:49:13) 
[GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> l=[1,2,3]
>>> r=l
>>> l
[1, 2, 3]
>>> r
[1, 2, 3]
>>> l.append(4)
>>> l
[1, 2, 3, 4]
>>> r
[1, 2, 3, 4]


中身をコピーするときにはどうするのかな。
-----
(追記)

コメントで教えて貰ったが、[:]で全体を指定するのであった。

$ python
Python 2.5 (r25:51918, Sep 19 2006, 08:49:13) 
[GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> l=[1,2,3]
>>> m=l[:]
>>> m
[1, 2, 3]
>>> l.append(4)
>>> l
[1, 2, 3, 4]
>>> m
[1, 2, 3]
>>> 


-----
(追記 9/29/2010)

二次元配列の場合、deepcopyを使います。
a[:][:]とやってもうまくゆきません。


>>> from copy import deepcopy
>>> a = [[ 0 for i in xrange(3)] for j in xrange(4)]
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> b = deepcopy(a)
>>> c = a[:][:]
>>>
>>> a[1][1] = 3
>>> a
[[0, 0, 0], [0, 3, 0], [0, 0, 0], [0, 0, 0]]
>>> b
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] #これはうまくできました
>>> c
[[0, 0, 0], [0, 3, 0], [0, 0, 0], [0, 0, 0]] #これはダメです
>>>

以下を参照。
http://docs.python.org/library/copy.html



6 comments:

cobacco said...

Listのコピーは

a = [0,1,2]
b = a[:]

ですよ

Tsuchiya Yoshihiro said...

なるほど!Thank you!

Anonymous said...

Google先生でここにたどり着きました.
仕事で数値計算をしたらこれのせいで上手くいかずに困っていたところで,これで解決できそうです.

ありがとうございました.
いや,本当に世の中には神がいるものですね・・・.

Anonymous said...

学校でならったのは、

b = list(a)

これで二次元配列もOK

Tsuchiya Yoshihiro said...

list()は参照のコピーなんじゃないですかね。
aを変更すると、bも書き変わってしまいます。

>>> a = [[ 0 for i in xrange(3)] for j in xrange(4)]
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> b = list(a)
>>> b
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[1][1] = 3
>>> a
[[0, 0, 0], [0, 3, 0], [0, 0, 0], [0, 0, 0]]
>>> b
[[0, 0, 0], [0, 3, 0], [0, 0, 0], [0, 0, 0]]

Anonymous said...

すいません。
二次元はだめでした。
板汚しでごめんなさい。