데이터를 복사할 때 깊은 복사(Deep Copy)와 얕은 복사(Swallow Copy)가 존재합니다.
C++에서는 포인터 등의 얕은 복사는 여러 문제를 야기하는 요인 중 하나입니다.
C++에서 힙에 생성한 메모리를 해제된 이후에 다른 변수에서 참조하면 문제가 발생하게 됩니다.
깊은 복사와 얕은 복사의 메모리 개념은 아래의 포스팅의 이미지를 참조하면 됩니다.
2015/01/14 - [Programming/C&C++] - 얕은 복사(Shallow Copy) vs 깊은 복사(Deep Copy)
앝은 복사는 다른 변수가 동일한 메모리를 가리키게 됩니다.
파이썬에서 리스트를 대입해서 생성하는 경우 얕은 복사가 발생하게 됩니다.
myList1 = [1, 2, 3, 4] myList2 = myList1 print(hex(id(myList1))) print(hex(id(myList2))) myList1[2] = 100 print(myList1[2]) print(myList2[2])
두 변수의 주소가 동일하게 출력되는 것을 확인할 수 있습니다.
myList1의 세 번째 값을 변경하면 myList2의 세 번째 값 역시 영향을 받게 됩니다.
파이썬에서는 추가적으로 다음과 같은 복사 방법을 제공합니다.
myList1 = [1, 2, 3, 4] myList2 = myList1.copy() myList3 = myList1[:] myList4 = list(myList1) print(hex(id(myList1))) print(hex(id(myList2))) print(hex(id(myList3))) print(hex(id(myList4))) myList1[2] = 100 myList2[2] = 101 myList3[2] = 102 myList4[2] = 103 print(myList1[2]) print(myList2[2]) print(myList3[2]) print(myList4[2])
파이썬 list의 메소드 중 하나인 copy()로 깊은 복사를 실행할 수 있습니다.
그리고 슬라이싱과 list() 생성자를 통해서 생성을 할 수 있습니다.
각각의 리스트가 전부 다른 주소를 가리키며 각각의 요소를 변경해도 영향을 받지 않습니다.
이렇게 모든 것이 완벽하면 좋겠지만 list 안에 list가 포함된 중첩된 구조에서 문제가 발생합니다.
myList1 = [1, 2, [3, 4], 5] myList2 = myList1.copy() print(hex(id(myList1))) print(hex(id(myList2))) print(hex(id(myList1[2]))) print(hex(id(myList2[2])))
리스트 자체의 주소는 다르지만 내부의 [3, 4]의 주소는 동일하게 출력됩니다.
list 안의 list는 정상적인 깊은 복사가 발생하지 않은 것입니다.
그래서 파이썬의 copy에는 deepcopy()라는 메소드가 지원됩니다.
deepcopy를 사용하기 위해서는 copy 라이브러리를 먼저 import하고 사용할 수 있습니다.
import copy myList1 = [1, 2, [3, 4], 5] myList2 = copy.deepcopy(myList1) print(hex(id(myList1))) print(hex(id(myList2))) print(hex(id(myList1[2]))) print(hex(id(myList2[2])))
deepcopy()를 사용해서 파이썬의 깊은 복사를 사용할 수 있습니다.
'Programming > Python' 카테고리의 다른 글
1. Django-dashing으로 IoT 대시보드 생성 (2) | 2017.01.24 |
---|---|
파이썬 가변인자 함수 사용 (0) | 2016.12.28 |
PyCharm으로 파이썬 프로젝트에 virtualenv 적용하기 (4) | 2016.03.07 |
파이썬 pip로 패키지 설치하기 (0) | 2016.03.03 |
zip 파일 압축/해제 방법 (0) | 2015.11.07 |