간단설명)
Shallow Copy
- 원본의 1차 객체만을 복사. 그 객체보다 아래의 객체를 복사하진 않음
- 그래서 원본에서 1차 객체 아래의 객체에 변동이 있으면 복사본에서도 변동이 있음
Deep Copy
- 원본의 1차 객체와 그 밑 객체를 모두 복사함.
- 그래서 원본에서 변동이 있더라도 복사본에는 변동이 없음
귀염뽀짝)
일단, 간단한 리스트 하나를 만들어보죠.
a = [[1, 2], [3, 4]]
아, 정말이지 귀염뽀짝한 리스트 a입니다.
b??)
이번엔 a를 복사하여 친구 b를 만들어봅시다.
리스트에는 copy()라는 간편한 메서드가 있습니다. 말 그대로 복사를 해주죠.
b = a.copy()
이렇게 복사를 완료하면 a도 [ [1, 2], [3, 4] ] b도 [ [1, 2], [3, 4] ] 으로 설정됩니다.
a를 바꿔주죠)
사실 전 a가 맘에 들지 않습니다. [ [5, 2], [3, 6] ] 으로 바꿔줍니다.
a[0][0] = 5
a[1][1] = 6
자 이제 a는 [ [5, 2], [3, 6] ] 가 됐습니다. b는 어떨까요?
a = [[1, 2], [3, 4]]
b = a.copy()
a[0][0] = 5
a[1][1] = 6
print(b)
>>> [[5, 2], [3, 6]]
잉??)
이게 어떻게 된 걸까요? 분명 코드에선 a의 리스트 내 리스트를 변경해준것 뿐인데 어떻게 이렇게 된걸까요?
아래 그림을 봅시다.
copy()라는 메서드를 사용하게 되면 위의 그림처럼 b가 a를 복사합니다. b가 a로부터 복사하는 것은 원본의 1차 컬렉션 객체뿐입니다. 그 아래의 child 객체들은 복사하지 못하죠. 이러한 복사방식을 Shallow Copy라고 부릅니다.
따라서 a가 2차 객체의 숫자들을 변동해도 b의 1차 객체는 변동된 a의 2차 객체를 그대로 참조합니다. 그래서 위에 a의 값이 변동됐지만 b도 값이 똑같이 변동된 겁니다.
그럼 어떡하죠?)
저흰 조금 더 깊숙이 복사해 볼 필요가 있습니다.
import copy
a = [[1, 2], [3, 4]]
b = copy.deepcopy(a)
a[0][0] = 5
a[1][1] = 6
print(a)
print(b)
copy라는 모듈을 먼저 import 해줍시다.
copy 모듈의 deepcopy() 함수는 1차 객체 그 밑의 객체들까지 복사하게 해 줍니다.
밑에 그림을 보시죠.
shallow copy에서 1차 객체만 복사한 것과는 달리 deep copy에서는 b가 2차 객체들까지 복사한 것을 볼 수 있습니다.
따라서 a의 2차 객체가 5를 가리키고 있을때 b의 2차 객체는 여전히 1을 가르키고 있는 거죠.
1이 5로 변하는 것이 아닌 이유는 정수형 객체는 immutable하기 때문입니다. 그러므로 기존의 1이 5로 변하는것이 아니라 새로운 객체 5를 참조하게 됩니다.
정리)
Shallow Copy:
- 복사본은 원본의 1차 객체 밖에 복사하지 못합니다.
- 그러므로 원본 1차보다 더 깊은 객체의 변동을 똑같이 참조하게 됩니다.
- 이 방식을 사용하려면 리스트 한정 a.copy() 또는 copy 모듈을 import 했다는 가정하에 copy.copy(a)를 실행합니다.
Deep Copy:
- 복사본은 원본의 모든 객체를 복사합니다.
- 그러므로 원본의 1차보다 더 깊은 객체의 변동은 복사본에 영향을 미치지 않습니다.
- 이 방식을 사용하려면 copy 모듈을 import 했다는 가정하에 copy.deepcopy(a)를 실행합니다.
정말 Shallow copy, Deep copy는 학교에서 매번 배워도 까먹고 또 까먹네요 ㅎㅎ...
코딩에 배움은 끝이 없고 블로그는 훌륭한 복습 장치인 거 같습니다!
오늘도 설명에 질문이나 잘못된 부분 있다면 알려주시면 감사하겠습니다 :)
참고자료:
Do it! 자료구조와 함께 배우는 알고리즘 입문 : 파이썬 편
'[Python]' 카테고리의 다른 글
[Python 공부] 리스트의 메소드 (0) | 2023.09.05 |
---|---|
[Python 공부] 리스트의 기초? (0) | 2023.08.29 |
[Python 공부] 탐욕의 알고리즘: Greedy Algorithm (0) | 2023.08.05 |
[Python 공부] Binary Search (0) | 2023.05.09 |
[Python 공부] Call by Object Reference (0) | 2023.05.07 |