개요

혹시 엑셀을 사용하면서 이런 생각 해본적 있을까?
엑셀에 값을 넣고 복사해서 붙여넣으려고 한다.
Image
이렇게 복사한 뒤 붙여넣으려고 보니 다른 곳에 붙여넣기 전에 이 원본을 삭제해도 괜찮을까? 하는 생각이 든다.

엑셀은 임시 메모리 공간에 실제 값을 복사한 뒤 저장한다. 그러니 기존 데이터를 삭제해도 상관이 없는 것이다.
또한 원본 값을 변경해도 복사본의 값은 변경되지 않는다.

이번에는 다르게 복사해보자. 첫 번째 셀에 100이라는 값을 넣고 그 밑의 칸에 =A1과 같이 작성했다.
Image 그런 뒤 A1의 값을 변경하면… Image 이런 식으로 복사본의 값도 변경된다.

깊은 복사와 얕은 복사를 이렇게 비유할 수 있다.

거칠게 이해하기

깊은 복사는 이처럼 원본의 값을 변경해도 변경본이 바뀌지 않고 반대도 마찬가지다. 얕은 복사는 원본의 값을 변경하면 복사본의 값도 바뀐다.

값 타입과 참조 타입

데이터 타입에는 2가지가 있다.
값 타입은 각각 고유의 메모리를 소유한다.
참조 타입은 주소값을 공유한다.

예를 들어 다음과 같이 코드를 작성했다.

int a = 100;
int b = a;
b = 200;

b의 값을 이렇게 변경한다고 해도 변수 a, b는 서로 영향을 미치지 않는다. 왜냐하면 C에서는 기본 데이터 타입은 값을 복사하는 방식으로 동작하기 때문이다.

만약 둘이 같은 주소를 참조하도록 하려면 포인터를 사용해야한다.

다음과 같은 파이썬 코드를 보자.

arr = [[0] * len(friends)]*len(friends)

[0, 0, 0,….., 0]과 같은 리스트를 만들고 * length만큼 반복한다.
그러나 파이썬에서 List는 대표적인 변경 객체로 얼핏 보기엔 2차원 리스트가 만들어진 것 같지만 결국 이렇게 생성된 여러 줄의 리스트는 하나의 참조를 가진다. 따라서 arr[4][0] = 1과 같이 변경하려고 해도 모든 행의 값이 변경된다.

따라서 사용하는 각 언어가 어떤 방식으로 동작하는지, 그리고 어떤 방법으로 얕은 복사와 깊은 복사를 사용할 수 있는지 아는 것이 중요한다.

위에서 작성한 파이썬 코드는 다음과 같이 깊은 복사로 대체할 수 있다.

arr = [[0] * len(friends) for _ in range(len(friends))]