1) 할당(Assignment)
2) 얕은 복사(Shallow copy)
3) 깊은 복사(Deep copy)
얕은 복사에 할당도 포함됨
복사 방법을 알기 전에 mutable객체와 immutable 객체의 차이에 대해 알아보자
구분 | 타입 |
---|---|
Immutable(수정 불가능한 객체) | int, float, str, tuple |
Mutable(수정 가능한 객체) | list, dict |
(1) Immutable 객체 예시(int)
a = 1
print(hex(id(a))) # 0x7fae9621b7a0
b = 1
print(hex(id(a))) # 0x7fae9621b7a0
print(a == b) # True
a += 1
print(hex(id(a))) # 0x7fae9621b7c0
a 와 b 를 따로 생성했으나 같은 주소를 가리키는 걸 볼 수 있음, a 값이 변경되니 참조하는 주소가 바뀌었음
a = 'HIHI'
b = 'HIHI'
print(hex(id(a)), hex(id(b))))
# 0x7f0b17fd6c70 0x7f0b17fd6c70
a = a.replace('HI', 'JI')
b = 'JIJI'
print(hex(id(a)), hex(id(b))))
# 0x7f0b0caf7d50 0x7f0b17fe9e30
(2) mutable 객체 예시 (list)
a = [1, 2, 'a']
b = [1, 2, 'a']
print(hex(id(a)), hex(id(b)))
# 0x7fcf5b8fbd48 0x7fcf5c3b4408 -> 같음
a.append(10)
b.append(10)
print(hex(id(a)), hex(id(b)))
# 0x7fcf5b8fbd48 0x7fcf5c3b4408 -> 같음
a = [1, 2, [1, 2]]
b = [1, 2, [1, 2]]
print(hex(id(a[0])), hex(id(b[0])))
# 0x7f1191d867a0 0x7f1191d867a0 (같음)
print(hex(id(a[1])), hex(id(b[1])))
# 0x7f1191d867c0 0x7f1191d867c0 (같음)
print(hex(id(a[2])), hex(id(b[2])))
# 0x7f1185f8fcc8 0x7f1187393d08 (다름)
즉, 배열 안에 있는 각각의 immutablle 요소는 같은 주소를 가지지만, mutable 요소는 다른 주소를 가짐
(1) immutable 객체 할당 (int)
a = 30
b = a
b += 1
print(a, b) # 30, 31
-> 같은 주소를 가리키며, 값을 변경했을 때 다른 주소를 가리킴 (각기 다른 참조)
(2) mutable 객체 할당 (list)
original_list = [1, 2, 3]
copy_list = original_list
print(original_list, copy_list)
# [1, 2, 3] [1, 2, 3]
copy_list[0] = 1000
print(original_list, copy_list)
# [1000, 2, 3] [1000, 2, 3]
같은 주소를 가리키며, 값이 변경되어도 참조하는 주소가 동일함
즉, 해당 주소의 일부 값을 변경하는 경우 이를 참조하는 모든 변수에 영향을 줌
(1) slice 연산자 사용
original_list = [1, 2, 3]
copy_list = original_list[:]
print(original_list, copy_list)
# [1, 2, 3] [1, 2, 3]
copy_list[0] = 1000
print(original_list, copy_list)
# [1, 2, 3] [1000, 2, 3]
할당과는 다르게 다른 주소에 연산된 결과를 복사
하지만, 리스트안에 있는 리스트 or 딕셔너리 등은 똑같이 복사하지 못함
original_list = [1, 2, [1, 2]]
copy_list = original_list[:]
print(original_list, copy_list)
# [1, 2, [1, 2]] [1, 2, [1, 2]]
copy_list[0] = 1000
print(original_list, copy_list)
# [1, 2, [1, 2]] [1000, 2, [1, 2]]
copy_list[2][0] = 2000
print(original_list, copy_list)
# [1, 2, [2000, 2]] [1000, 2, [2000, 2]]
original_list = [1, 2, {'name': 'chaelin', 'id': 1}]
copy_list = original_list[:]
print(original_list, copy_list)
# [1, 2, {'name': 'chaelin', 'id': 1}] [1, 2, {'name': 'chaelin', 'id': 1}]
copy_list[2].update(name='chaechae')
print(original_list, copy_list)
# [1, 2, {'name': 'chaechae', 'id': 1}] [1, 2, {'name': 'chaechae', 'id': 1}]
(2) import copy 사용
import copy
original_list = [1, 2, [3, 4]]
copy_list = copy.copy(original_list)
print(original_list, copy_list)
# [1, 2, [3, 4]] [1, 2, [3, 4]]
copy_list[0] = 1000
print(original_list, copy_list)
# [1, 2, [3, 4]] [1000, 2, [3, 4]]
copy_list[2][0] = 2000
print(original_list, copy_list)
# [1, 2, [2000, 4]] [1000, 2, [2000, 4]]
import copy
original_list = [1, 2, [3, 4]]
copy_list = copy.deepcopy(original_list)
print(original_list, copy_list)
# [1, 2, [3, 4]] [1, 2, [3, 4]]
copy_list[0] = 1000
print(original_list, copy_list)
# [1, 2, [3, 4]] [1000, 2, [3, 4]]
copy_list[2][0] = 2000
print(original_list, copy_list)
# [1, 2, [3, 4]] [1000, 2, [2000, 4]]
Image by Ylanite Koppens from Pixabay