아주 최소한만 복사한다. 메모리에 생성되는 것이 아닌 '참조'만 복사한 것을 의미한다.
mutable한 객체일 경우에 같은 주소를 바라보게 된다. 슬라이싱과 헷갈릴 수 있으므로 예제를 살펴보자.
a = [1, 2, 3, 4, 5]
b = a
a[1] = 999
print(f'a의 값은 : {a}')
print(f'b의 값은 : {b}')
# 결과값
# a의 값은 : [1, 999, 3, 4, 5]
# b의 값은 : [1, 999, 3, 4, 5]
b = a
와 같이 사용할 경우 a의 값을 복사하길 원했는데 '주소값'을 공유하게 된다.
그럼 어떻게 해야할까? 👉 슬라이싱을 이용하면 된다.
슬라이싱을 이용하게 될 경우 '새 리스트'가 만들어지므로 같은 주소를 참조하지 않게 되며 위 문제를 해결할 수 있다.
a = [1, 2, 3, 4, 5]
b = a[:]
a[1] = 999
print(f'a의 값은 : {a}')
print(f'b의 값은 : {b}')
# 결과값
# a의 값은 : [1, 999, 3, 4, 5]
# b의 값은 : [1, 2, 3, 4, 5]
중요한 점은, 슬라이싱으로 만들어낸 배열은 '얕은 복사'라는 것이다.
첫 줄에 얕은 복사를 설명했던 아주 최소한만 복사한다. 메모리에 생성되는 것이 아닌 '주소값'을 복사하여 같은 메모리를 참조하게 된다.
이 설명과 달리 a, b배열은 주소값도 다른 것 같은데 왜 그럴까?🤔
두번째 줄을 잘 읽어보자 mutable한 객체일 경우에 같은 주소를 바라보게 된다.
여기서 mutable은 '값이 변경 될 수 있다'라는 것을 의미한다.
즉 a, b배열의 주소값이 문제가 아니라 어떤 값이 들어있느냐의 문제이다.
예제를 살펴보자.
a = [1, [2, 3], 4, 5]
b = a[:]
a[1][0] = 999
print(f'a의 값은 : {a}')
print(f'b의 값은 : {b}')
처음 예제와 달리 이차원 배열을 만들어보았고 그 안에 있는 값을 수정해보았다.
결과는 다음과 같다.
a의 값은 : [1, [999, 3], 4, 5]
b의 값은 : [1, [999, 3], 4, 5]
슬라이싱을 이용했음에도 불구하고 값이 수정되어 버렸다.
b = a.copy()
import copy
b = copy.copy(a)
앞서 얕은 복사의 문제점을 해결하기 위해서는 깊은 복사를 이용해야 한다.
깊은 복사는 리스트, 딕셔너리 등 mutable 한 객체를 모두 새로 만들어준다.
import copy
a = [1,[2,3],4,5]
b = copy.deepcopy(a)
a[1][0] = 999
print(f'a의 값은 : {a}')
print(f'b의 값은 : {b}')
# 결과값
# a의 값은 : [1, [999, 3], 4, 5]
# b의 값은 : [1, [2, 3], 4, 5]