728x90
immutable object와 mutable object에 대한 사전 지식이 필요한 포스팅입니다.
shallow copy
- a는 원본, b는 a를 복사한 복사본이라고 하자.
- shallow copy를 하면 같은 메모리 주소를 바라본다.
- 이 때, b 또는 a의 값을 바꿀 경우, 이 둘이 immutable인지, mutable인지에 따라 상황이 바뀐다.
immutable object
- immutable object의 경우, b의 값을 바꾸는 경우는 다른 메모리 주소에 값을 넣고, 이 메모리 주소를 참조한다는 뜻이 된다.
- 따라서 a에게 영향을 주지 않고, b의 값만 바뀐다.
>>> a = "abc"
# shallow copy
>>> b = a
# 값 확인
>>> a
'abc'
>>> b
'abc'
# 메모리 주소 확인
>>> id(a)
4387454680
>>> id(b)
4387454680
# b에 다른 값을 할당하면 b는 다른 메모리 주소를 참조한다.
>>> b = "abcd"
# 값 확인
>>> a
'abc'
>>> b
'abcd'
# 메모리 주소 확인
>>> id(a)
4387454680
>>> id(b)
4396456400
mutable object
- mutable object의 경우, b를 바꾸면 ‘mutable’하기 때문에 같은 메모리 주소에서 값을 바꾸는 작업을 하게 된다.
- 그리고 b와 a는 같은 메모리 주소를 바라보고 있기 때문에, b의 값을 바꾸면(즉, b가 바라보고 있는 메모리 주소의 상태를 바꾼다는 뜻), a에 영향을 주게 된다.
>>> a = [1, 2, 3]
>>> b = a # shallow copy
# b의 상태를 변경한다. list는 mutable object이므로, 메모리 주소는 동일하며
# b[0]만 재할당 되는 방식이다.
>>> b[0]= 5
# 값 확인
>>> a
[5, 2, 3]
>>> b
[5, 2, 3]
# 메모리 주소 확인
>>> id(a)
4396179528
>>> id(b)
4396179528
list slicing을 활용한 copy
list sling을 통한 새로운 값을 할당하면, 새로운 id가 부여되며, 서로 영향을 받지 않는다.
>>> a = [1,2,3]
# list slicing을 통한 copy
>>> b = a[:]
# 메모리 주소가 다른 것을 확인할 수 있다.
>>> id(a)
4396179528
>>> id(b)
4393788808
# a와 b의 값이 같은지 확인
>>> a == b
True
# 하지만, a와 b는 다른 주소를 바라보고 있으므로 다른 객체이다.
>>> a is b
False
# b를 바꾸면
>>> b[0] = 5
# a에는 영향이 가지 않는다.
>>> a
[1, 2, 3]
>>> b
[5, 2, 3]
- 하지만, slicing을 통한 복사도 얕은 복사(shallow copy)이다.
- list 안에 list와 같은 형식의 mutable 안에 mutable이 있는 경우에 이런 복사 방식이 문제가 될 수 잇다.
- id(a)와 id(b)는 다른 값, 즉 다른 메모리 주소를 참조히자만, 그 내부의 객체 id(a[0])과 id(b[0])의 경우, 같은 주소를 바라보고 있기 때문이다.
>>> a = [[1,2], [3,4]]
>>> b = a[:]
>>> id(a)
4395624328
>>> id(b)
4396179592
>>> id(a[0])
4396116040
>>> id(b[0])
4396116040
- 이 때, a의 원소를 재할당 하는 경우에는 문제가 되지 않는다.
>>> a[0] = [8,9]
>>> a
[[8, 9], [3, 4]]
>>> b
[[1, 2], [3, 4]]
>>> id(a[0])
4393788808
>>> id(b[0])
4396116040
- 문제는, a의 원소의 내부의 값을 변경하면 b에도 영향이 간다는 점이다.
>>> a[1].append(5)
>>> a
[[8, 9], [3, 4, 5]]
>>> b
[[1, 2], [3, 4, 5]]
>>> id(a[1])
4396389896
>>> id(b[1])
4396389896
- copy 모듈의 copy method 또한 shallow copy이다.
deep copy
deepcopy는 이러한 문제를 해결한, 내부 객체들까지 모두 새롭게 copy되는 방식이다.
>>> import copy
>>> a = [[1,2],[3,4]]
>>> b = copy.deepcopy(a)
>>> a[1].append(5)
>>> a
[[1, 2], [3, 4, 5]]
>>> b
[[1, 2], [3, 4]]
참고자료
728x90
'정리' 카테고리의 다른 글
mutable vs immutable object (0) | 2024.03.04 |
---|---|
Likelihood와 MLE(Maximum Likehood Estimation, 최대우도추정법) (0) | 2023.04.14 |
Bayse's rule(베이즈 정리) (0) | 2023.04.13 |
[colab+spark] colab에서 spark 쓰는법 (0) | 2021.12.01 |
[DataScience 기초](정리 필요) group-k fold (0) | 2021.10.27 |