티스토리 뷰

파이썬에서 원래있던 리스트과 똑같은 리스트을 만들고 만든 리스트을 수정할때 원래의 리스트은 바뀌지 않으려면 어떻게 해야할까요?


일반적으로 똑같은 리스트을 만드려고 하면 

a = [1,2,3]
b = a
print(id(a)) #16964584
print(id(b)) #16964584


위와같이 b = a 대입하면 되는거 아니야? 라고 생각하실겁니다.


하지만 위의 소스에서 b를 변경하게 되면 a도 변하게 될 것입니다.


a 와 b는 같은 객체를 참조하고 있기 때문이죠.


a is b 는 True이며 3,4번째 줄에서 출력한 주소값은 같을 것입니다.



그럼 어떻게하면 바뀌지 않게할까요?



방법은 얕은 복사와 깊은 복사가 있습니다.


두 방법의 공통점은 참조가 아니라 복사본을 만드는 것입니다.


새로운 객체를 생성하는 것이죠.


차이점은 얕은 복사는 새로운 객체 안에 원래 있던 객체를 참조하여 채워지고,


깊은 복사는 새로운 객체를 생성하고 원래 객체가 담고 있던 모든 객체를 재귀적으로 복사하게 됩니다. 



이게 무슨말이냐 하실텐데요


먼저 얕은 복사부터 예시를 들어보겠습니다. 

a = [1,2,[3,4]]
b = list(a) # 얕은복사
b.append(100)
print(a) #[1,2,[3,4]]
print(b) #[1,2,[3,4],100]

b[2][0] = [5]

print(a)#[1,2,[5,4]]
print(b)#[1,2,[5,4],100]


얕은 복사를 하고 b에 100을 추가하였을때는 a가 변하지 않았지만 기존 원소를 변경하니 a에도 적용이 되었습니다.


이유는 a,b는 별개의 리스트지만 그 안의 원소를 참조하여 채워 공유를 하고있기 때문입니다.


만약 b[3] = 200 으로 변경을 하게되면 b만 변경이 될 것입니다. 


추가한 원소는 b의 단독적인 원소이기 때문입니다.


+ a = [1,2,3] 

   b = [a]  #[[1,2,3]]

   이 방법도 얕은 복사입니다.


이것을 해결해주는 방법이 깊은 복사입니다.

 

import copy
a = [1,2,[3,4]]
b = copy.deepcopy(a) #깊은 복사
b[2][0] = 100
print(a) #[1.2.[3,4]]
print(b) #[1,2,[100,4]]


깊은 복사는 표준 라이브러리에 들어있는 copy.deepcopy()를 사용합니다.


b의 원소를 변경했음에도 a의 원소가 바뀌지 않은 것을 볼 수 있습니다.




'Programing-Language > Python' 카테고리의 다른 글

python console 지우기  (2) 2018.02.12
Python None  (0) 2018.01.07
python virtualenv 윈도우 설치/사용  (0) 2017.11.19
Python 삼항 연산자  (0) 2017.11.17
range,xrange  (0) 2017.09.18
댓글