assignment는 복사의 개념이 아니고 같은 객체를 가리키게 만드는 것(대입)이다.
a = [1,2,3]
b = a
여기서 b는 a가 가리키는 동일한 리스트 객체를 참조하게 된다.
shallow copy는 겉모양만 복사하고 내부에 있는 객체들은 공유하는 복사 방식이다.
original = [[1,2], [3,4]]
shallow = copy.copy(original)
shallow[0][0] = 999
print("original:", original) # [[999, 2], [3, 4]]
print("shallow:", shallow) # [[999, 2], [3, 4]]
내부 요소(중첩된 리스트)는 원본과 같은 객체를 참조하기 때문에 내부 값을 변경하면 원본에도 영향을 미친다.
import copy
original = [[1,2], [3,4]]
deep = copy.deepcopy(original)
deep[1][1] = 888
print("original:", original) # [[1,2], [3,4]]
print("deep :", deep) # [[1, 2], [3, 888]]
deep copy는 전체 리스트(겉 리스트와 안에 있는 리스트 모두)를 복사한 값이므로 원본의 값에는 영향을 미치지 않는다.
import copy
original = [[1, 2], [3, 4]]
assigned = original # 그냥 대입
shallow = copy.copy(original) # 얕은 복사
deep = copy.deepcopy(original) # 깊은 복사
assigned[0][0] = 100
shallow[1][1] = 200
deep[0][1] = 300
print("original :", original)
print("assigned :", assigned)
print("shallow :", shallow)
print("deep :", deep)
--------------------------------------
# 결과
original : [[100, 2], [3, 200]]
assigned : [[100, 2], [3, 200]]
shallow : [[100, 2], [3, 200]]
deep : [[1, 300], [3, 4]]
위의 내용을 표로 정리하면 다음과 같다.
| 구분 | 겉 리스트 (바깥 객체) | 안쪽 리스트 (내부 객체) | 원본 영향 여부 | 설명 |
|---|---|---|---|---|
assignment | 공유 (같은 객체) | 공유 (같은 객체) | O | 변수만 새로 만들고, 원본과 동일한 객체 참조 |
shallow copy | 새 객체 | 공유 (같은 객체) | O | 바깥 리스트는 새로 생성, 내부는 원본과 공유 |
deep copy | 새 객체 | 새 객체 | X | 바깥 리스트와 내부 요소 모두 새로 복사 |