mutable & immutable / Shallow & Deep copy

EBAB!·2024년 1월 17일
0

파이썬에서 선언을 할 때 기본 원리를 알아야 참조에 대한 실수가 없다.

a = 100
b = a
b = 10
print(a)  # 100

a = [100]
b = a
b[0] = 10
pritn(a)  # [10]

a = (100,)
b = a
b = 10
print(a)  # (100)

위의 원리는 하나다.
좌변은 변수, 우변은 참조 객체이다.
참조 객체(a)가

  1. 불변 객체(int, str, float, tuple 등)일 때
    변수(b)가 새로운 객체를 참조받는다면 변수는 새로운 객체를 생성하고 참조한다.
  2. 가변 객체(list, dict 등)일 때
    변수(b)가 새로운 객체를 참조받는다면 변수는 동일한 객체의 참조를 공유한다.

오해하지 않아야 하는 점은 가변 객체는 내부의 요소를 변경할 수 있다라는 점이다.

a = [100]
b = a
b = 10
print(a)  # [100]

여기서 b = 10을 하는 순간 list 요소가 아닌 list자체를 바꾸는 것이므로 b10이라는 새로운 객체를 할당받게 되는 것이다.

이런 기본 원리를 알아야 copy에서의 실수가 없다.

Shallow Copy

해석 그대로 얕은 복사를 의미한다.

import copy

a = [10, 20, 30]
b = copy.copy(a)
print(id(a), id(b))  # 140456783782272, 140573327194048
b.append(40)
print(a)  # [10, 20, 30, 40]

언뜻보면 b = a를 했을 때와 같아 보이지만 주소값이 다른 것을 확인할 수 있다.

b = a 일 때는 두 주소값이 같았기에 이것이 의미하는건 변수명만 다르고 같은 주소를 참조하는 것이다.
반면 b = copy.copy(a)를 통해 shallow copy를 하면 a와 별개의 객체를 가리키는 b가 생성되지만 그 내부의 요소들은 같은 a,b가 공유되고 있다.

이 때문에 복사는 하지만 얕은 복사라 한다.

Deep Copy

깊은 복사를 의미하고 완전히 같은 형태의 새로운 객체를 복사한다. 앞의 복사와 달리 완전한 별개의 객체가 생성된다.
당연히 그만큼 메모리가 사용되므로 큰 사이즈의 객체를 다룰 때 조심히 사용해야 한다.

import copy

a = [10, 20, 30]
b = copy.deepcopy(a)
print(a, b)  # 140456783782272, 140573327194048
b.append(40)
print(a)  # [10, 20, 30]
print(b)  # [10, 20, 30, 40]
profile
공부!

0개의 댓글