파이썬에서 리스트나 딕셔너리 같은 가변 객체(mutable object) 를 다룰 때 “복사”는 중요한 주제입니다.
단순히 변수에 할당하는 것과, copy.copy() (얕은 복사), copy.deepcopy() (깊은 복사)는 동작 방식이 전혀 다릅니다.
이번 글에서는 코드 예제와 함께 복사의 종류를 정리해 보겠습니다.
1. 단순 할당 (Copy) — 주소 공유
a_list = [1, 2, 3, 4]
b_list = a_list
print(id(a_list))
print(id(b_list)) # 같은 주소
- b_list = a_list 는 새로운 리스트를 만드는 게 아닙니다.
- 두 변수는 같은 객체(주소)를 가리키는 별명(alias) 역할만 합니다.
- 따라서 하나를 바꾸면 다른 것도 바뀝니다.
b_list[2] = 100
print(a_list) # [1, 2, 100, 4]
print(b_list) # [1, 2, 100, 4]
2. 얕은 복사 (Shallow Copy)
import copy
c_list = [1, 2, 3, [4, 5, 6], [7, 8, 9]]
d_list = copy.copy(c_list)
print(id(c_list))
print(id(d_list)) # 서로 다른 주소
- copy.copy() 는 1차원 요소만 새로 복사합니다.
- 따라서 c_list 와 d_list 는 서로 다른 리스트가 되지만,
안에 있는 리스트(중첩 객체) 는 여전히 공유합니다.
d_list[1] = 100 # d_list만 바뀜
d_list[3].append(1000) # 내부 리스트는 공유 → c_list도 영향 받음
print(c_list) # [1, 2, 3, [4, 5, 6, 1000], [7, 8, 9]]
print(d_list) # [1, 100, 3, [4, 5, 6, 1000], [7, 8, 9]]
따라서 데이터 원본을 백업하고 1차원 요소만 분리하고 싶을 때 얕은 복사가 적합합니다.
3. 깊은 복사 (Deep Copy)
e_list = [1, 2, 3, [4, 5, 6], [7, 8, 9]]
f_list = copy.deepcopy(e_list)
print(id(e_list))
print(id(f_list)) # 완전히 다른 객체
- copy.deepcopy() 는 중첩된 객체까지 전부 새로운 객체로 복사합니다.
- 따라서 원본과 복사본은 완전히 독립적입니다.
f_list[3].append(1000)
f_list[4][1] = 10000
print(e_list) # [1, 2, 3, [4, 5, 6], [7, 8, 9]]
print(f_list) # [1, 2, 3, [4, 5, 6, 1000], [7, 10000, 9]]
4. Call by Value, Reference, 그리고 Python의 Call by Share
1️⃣ C 같은 언어: Call by Value (값만 전달) 또는 Call by Reference (주소 전달)
2️⃣ Python: Call by Sharing (공유 호출) 모델을 따릅니다.
- 객체의 참조(reference) 가 함수로 전달되지만,
- 그 참조 자체를 바꾸면 원본에는 영향 없음.
- 하지만 가변 객체의 내용을 수정하면 원본에 반영됩니다.
정리하면
- 단순 할당: 같은 객체를 공유 → 하나 바꾸면 다른 것도 바뀜
- 얕은 복사 (shallow copy): 1차원만 새 객체, 중첩 객체는 공유
- 깊은 복사 (deep copy): 중첩 객체까지 모두 새로 생성 → 완전 독립
- Python은 Call by Sharing 방식이므로, 복사를 어떻게 하느냐에 따라 결과가 크게 달라집니다.
'파이썬 > 기초 프로그래밍' 카테고리의 다른 글
| 파이썬 컨텍스트 매니저로 실행 시간 측정하기 (0) | 2025.09.13 |
|---|---|
| 파이썬 컨텍스트 매니저(Context Manager) 완전 정리 (0) | 2025.09.13 |
| Python 함수 재사용: lambda보다 내부 함수 구조가 좋은 경우 (0) | 2025.09.13 |
| Python map 객체와 형 변환 (0) | 2025.09.13 |
| Python 익명 함수(lambda) vs 일반 함수(def) (0) | 2025.09.13 |