백준 코드를 풀다가 어려워서 모범답안을 해설하는 중에 깊은 복사(deep copy) 개념이 나왔습니다.
복사에도 여러 종류가 있군요.
객체의 복사에는 얕은 복사(shallow copy)와 깊은 복사(deep copy)가 있습니다.
우선 docs.python.org의 개념정리입니다.
가변(mutable) 컬렉션 또는 가변(mutable) 항목들을 포함한 컬렉션의 경우,
때로 컬렉션을 변경하지 않고 사본을 변경하기 위해 복사(copy)가 필요합니다.
얕은 복사와 깊은 복사의 차이점은,
복합 객체(리스트 또는 클래스 인스턴스와 같은 다른 객체를 포함한 객체)에만 유효합니다.
▷ 얕은 복사: 새로운 복합 객체를 만들고,
(가능한 범위까지) 원본 객체를 가리키는 참조를 새로운 복합 객체에 삽입합니다.
▷ 깊은 복사: 새로운 복합 객체를 만들고,
재귀적으로 원본 객체의 사본을 새로 만든 복합 객체에 삽입합니다.
얕은 복사와 깊은 복사 모두 새로운 복합 객체를 만들지만 참조를 삽입하는지, 사본을 삽입하는지 차이가 있습니다.
모듈을 쓰지 않은 단순 복사와 모듈의 두 가지 복사를 좀 더 알아보겠습니다.
1. 단순 복사
a = [1, 2, 3, 4]
b = a #shallow copy
print(b) #[1, 2, 3, 4]
b[2] = 5 #b의 3을 5로 변경
print(b) #[1, 2, 5, 4]
print(a) #[1, 2, 5, 4]
a를 b에 할당해주었기 때문에, b와 a는 같은 객체의 주소를 바라봅니다.
b의 세 번째 인덱스 값을 변경하면, a의 세 번째 인덱스 값도 수정됩니다.
왜냐하면 두 변수가 같은 객체를 참조하기 때문입니다.
☞ 두 개의 변수 중 하나만 변경되면 나머지 하나도 동일하게 수정되는 특징을 갖습니다.
객체가 숫자나 문자열일 때, 값이 바뀌지 않는 불변(immutable)의 특징을 가지게 되는데,
이 때 위와 같은 개념이 적용되지 않습니다.
a = 100
b = a
print(b) # 100
b = 'abc'
print(b) # abc
print(a) # 100
2. 얕은 복사(shallow copy)
얕은 복사는 복합객체(리스트)를 새로 생성합니다. 그리고 그 안에 들어가는 내용은 원본과 같은 객체입니다.
import copy
a = [1, [1, 2, 3]]
b = copy.copy(a) #shallow copy
print(b) #[1, [1, 2, 3]]
b[0] = 50
print(b) #[50, [1, 2, 3]]
print(a) #[1, [1, 2, 3]]
b[0] 값은 숫자이고 불변(immutable)입니다.
복사된 리스트 b는 별도의 객체라서 b[0] 값을 수정하면 복사본에만 수정이 되고 원본리스트 a에는 수정이 되지 않습니다.
가변(mutable)값을 수정하면 어떻게 될까요?
c = copy.copy(a)
c[1].append(4)
print(c) #[1, [1, 2, 3, 4]]
print(a) #[1, [1, 2, 3, 4]]
c[1]은 리스트이기 때문에 가변(mutable)입니다.
a와 c의 내부리스트는 같은 객체를 참조하기 때문에 mutable 한 리스트를 변경하면 a와 c 모두 변경됩니다.
객체가 불변/가변인지에 따라 차이가 나타납니다.
3. 깊은 복사(deep copy)
깊은 복사는 복합 객체를 새로 생성하고, 원본 객체의 사본을 재귀적으로 생성합니다.
- 깊은 복사 구현 메서드: deepcopy()
import copy
a = [1, [1, 2, 3]]
b = copy.deepcopy(a) #deep copy
print(b) #[1, [1, 2, 3]]
b[0] = 5
b[1].append(4)
print(b) #[5, [1, 2, 3, 4]]
print(a) #[1, [1, 2, 3]]
깊은 복사를 수행하면, 원본 객체와 사본 객체가 서로 다른 대상이 됩니다.
따라서 한 쪽을 수정한 부분이 다른 쪽에 영향을 주지 않습니다.
'알고리즘-python > 개념 정리하기' 카테고리의 다른 글
[알고리즘/파이썬(Python3)] 캐시 알고리즘 중 LRU 알고리즘 (0) | 2021.07.13 |
---|---|
[자료구조/파이썬(Python3)] 힙 (Heap) (0) | 2021.07.08 |
백준 알고리즘 문제에서 입력 받기 (0) | 2020.07.09 |