2010-12-15 2 views
1

私はcsvファイルから行を読み込み、それらを操作して戻すpyスクリプトに取り組んでいます。これまでのところ、変換作業をリストするcsvがあります。なぜPythonの 'for'ループが参照されていないリストを変更するのですか?

私が抱えている問題は、一時的なリストを繰り返したときに、forループがすべての一時的なリストを変更するというものです。ここに、私が何を言おうとしているのかの簡単な例があります。

>>> l = [['hi', 'ho'],['no', 'go']] 
>>> t = [] 
>>> y = [] 
>>> 
>>> for row in l: 
...  row[0] = '123' 
...  y.append(row) 
...  t.append(row) 
... 
>>> y 
[['123', 'ho'], ['123', 'go']] 
>>> t 
[['123', 'ho'], ['123', 'go']] 

したがって、上記は簡単です(うまくいけば)。 (私はリストをコピーするだけでなく、他のことをしたいと思っています。単純にしておきたい)。

しかし、ここには私が手に入れない部分があります。

>>> z = [] 
>>> for row in y: 
...  row[0] = 'xxxx' 
...  z.append(row) 
... 
>>> z 
[['xxxx', 'ho'], ['xxxx', 'go']] 
>>> t 
[['xxxx', 'ho'], ['xxxx', 'go']] 
>>> y 
[['xxxx', 'ho'], ['xxxx', 'go']] 

私はサブリストの最初の部分を変更して、新しいリスト「Z」にそれを保存したい場合は、それは同様リストtを変更します!

ここでは何が起こっていますか? z、y、tは同じメモリ位置を指していますか?ここで何が起こっても

、?:

上記の質問に似て
>>> for rowx in y: 
...  rowx[0] = 'x55x' 
...  z.append(rowx) 
... 
>>> z 
[['xxxx', 'ho'], ['x55x', 'go'], ['x55x', 'go'], ['x55x', 'go']] 
>>> t 
[['xxxx', 'ho'], ['x55x', 'go']] 
>>> y 
[['xxxx', 'ho'], ['x55x', 'go']] 

は、なぜyは、tが変わっ取得しますか?

ありがとうございます!

答えて

4

あなたの3つのリストは異なっているが、それらの間で共有だけで2つの要素があります

>>> y[0] is t[0] is z[0] 
True 
>>> y[1] is t[1] is z[1] 
True 

isオペレータはあなたの参照が同じオブジェクトを指していることを示しています場合は、そのオブジェクトへの変更はありません表示されますあなたが使用する参照事項。あなたは要素のコピーをしたい場合は

これを避けるには、copyモジュールを使用します。

>>> import copy 
>>> a = copy.deepcopy(y) 
>>> a 
[['xxxx', 'ho'], ['xxxx', 'go']] 
>>> a[0] is y[0] 
False 
>>> a[0][0] = 'copy!' 
>>> y 
[['xxxx', 'ho'], ['xxxx', 'go']] 
+0

リストの浅いコピーについては、 'y [:]'を使用することができます – SingleNegationElimination

+0

ありがとうございました! [:]が答えて私の質問を解決している間、あなたのcopy.deepcopy解決策もそうです、それは浅いコピーが十分ではない(明らかに)ので私のスクリプトでやらなければならなかったものです。あなたは私の問題を解決しました! :) – RaytheonLiszt

+0

@Raytheon '[:]'スライス、単純な 'for'ループ、そして浅いコピーはまったく同じ効果を持っています。 –

7

Pythonには何もありませんしかしの参照。 rowは、lまたはyの実際の要素への参照です。 rowを突然変異させるとその要素が変異し、それを別のオブジェクトに追加すると元の要素が追加されます。

+4

'row [:]'を使用して 'row'のコピーを作成します。 – katrielalex

+0

@katrielalex:私はあなたのように、100回upvoteすることはできますか?私はリストの参照でOPの問題にぶつかったし、私の人生のための参照をコピーする代わりにリストをコピーする方法を見つけることができませんでした。すべてのリストスライスは、このような参照の代わりにコピーを返しますか? – DGH

+1

@DGH: 'list'の場合は、yesです。しかし、浅いコピー。 –

0

「?同じメモリ位置にZ、YおよびT指しています」

z [0]、y [0]、t [0]はありません(ただし、メモリ位置とは呼ばれませんがCではありません)。同じリスト['hi', 'ho']をz、y、tの両方に追加しています。それは同じリストです。同じリストにしたくない場合は、まずコピーを作成する必要があります。

関連する問題