2010-12-15 4 views
1

나는 csv 파일에서 라인을 읽고 조작 한 py 스크립트를 작성 중입니다. 지금까지 나는 변환 작업 목록을 CSV 있습니다.파이썬의 '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

귀하의 세 가지 목록은 다르지만, 그들 사이에 공유하는 두 요소가 다음과 같습니다 is 운영자가 사용자의 참조가 동일한 개체를 가리 있음을 알려줍니다 경우, 객체에 대한 변경

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

더 나타납니다은 당신이 사용하는 참조 사항. 당신은 요소의 사본을 원하는 경우

이를 방지하기 위해, 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

고맙다 jleedev! [:]가 대답하고 내 질문을 해결하는 동안 copy.deepcopy 솔루션도 마찬가지입니다. 이는 얕은 복사본이 충분하지 않기 때문에 스크립트에서해야만하는 것입니다 (외관상으로는). 당신은 내 문제를 해결했습니다! :) – RaytheonLiszt

+0

@Raytheon'[:]'슬라이스, 간단한'for' 루프, 그리고 얕은 복사는 모두 똑같은 효과를냅니다. –

7

파이썬에는 이 아니라 참조가 없습니다. rowl 또는 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가 아닙니다. z, y 및 t에 동일한 목록 ['hi', 'ho']을 추가하고 있습니다. 그래서 그것은 같은 목록입니다. 같은 목록이 아니길 원한다면 먼저 복사본을 만들어야합니다.

관련 문제