Tuesday, March 25, 2008

pythonメモ: 配列の初期化

これは間違い。

>>> c=[[0,0,0]]*3
>>> c
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> c[1][2]=3
>>> c
[[0, 0, 3], [0, 0, 3], [0, 0, 3]]
>>> 


[0,0,0]が示しているのが同じオブジェクトってことなんでしょうね。
以下だと思った通りの動きなのだが、一体、何が違うの、と言う感じ。

>>> d=[]
>>> d.append([0,0,0])
>>> d.append([0,0,0])
>>> d.append([0,0,0])
>>> d
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> d[1][2]=3
>>> d
[[0, 0, 0], [0, 0, 3], [0, 0, 0]]


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