파이썬에서 변수는 객체에 대한 참조일 뿐입니다. 따라서 다른 변수에 할당될 때 객체를 복사하지 않고 동일한 객체에 대한 다른 참조 역할을 합니다. id() 함수를 사용하여 확인할 수 있습니다.
>>> L1 = [1,2,3] >>> L2 = L1 >>> id(L1), id(L2) (2165544063496, 2165544063496)
위 코드의 결과는 두 목록 객체에 대한 id()가 동일하다는 것을 보여줍니다. 이는 둘 다 동일한 객체를 참조한다는 것을 의미합니다. L2는 L1의 얕은 복사본이라고 합니다. 둘 다 동일한 개체를 참조하므로 둘 중 하나를 변경하면 다른 개체에 반영됩니다.
>>> L1 = [1,2,3] >>> L2 = L1 >>> L2[1] = 100 >>> L1,L2 ([1, 100, 3], [1, 100, 3])
위의 예에서 인덱스 번호에 있는 항목입니다. L2의 1이 변경됩니다. 이 변경 사항이 두 가지 모두에서 나타나는 것을 볼 수 있습니다.
복사 작업으로 완전히 새로운 개체가 생성되고 중첩된 개체의 복사본도 여기에 재귀적으로 추가되는 경우 복사본을 깊은 복사라고 합니다.
Python 표준 라이브러리의 복사 모듈은 두 가지 방법을 제공합니다.
- copy.copy() – 얕은 사본 생성
- copy.deepcopy() – 전체 사본 생성
얕은 복사본은 새 개체를 만들고 원본 요소의 참조를 저장하지만 중첩 개체의 복사본을 만들지 않습니다. 중첩된 개체의 참조만 복사합니다. 결과적으로 복사 프로세스는 재귀적이지 않습니다.
>>> import copy >>> L1 = [[1,2,3], [4,5,6]] >>> L2 = copy.copy(L1) >>> L1,L2 ([[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]) >>> L2.append([10,10,10]) >>> L1,L2 ([[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6], [10, 10, 10]])
여기서 L1은 중첩 목록이고 L2는 얕은 복사본입니다. 상위 목록 개체에 대한 참조가 L2에 복사되지만 중첩된 요소는 복사되지 않습니다. 따라서 L2에 다른 목록을 추가하면 L1에 반영되지 않습니다.
그러나 자식 요소의 요소를 수정하려고 하면 해당 효과가 두 목록에서 모두 표시됩니다.
>>> L1 = [[1,2,3], [4,5,6]] >>> L2 = copy.copy(L1) >>> L1,L2 ([[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]) >>> L2[1][0] = 100 >>> L1,L2 ([[1, 2, 3], [100, 5, 6]], [[1, 2, 3], [100, 5, 6]])
그러나 깊은 복사는 새 개체를 만들고 원래 요소에 있는 중첩된 개체의 복사본도 재귀적으로 추가합니다.
다음 예에서 L2는 L2의 전체 복사본입니다. 이제 내부 목록의 요소를 변경하면 다른 목록에는 표시되지 않습니다.
>>> L1 = [[1,2,3], [4,5,6]] >>> L2 = copy.deepcopy(L1) >>> L1,L2 ([[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]) >>> L2[1][0] = 100 >>> L1,L2 ([[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [100, 5, 6]])
따라서 딥 카피의 효과는 출력으로 확인됩니다.