제목으로 어그로 조금 끌어봤다ㅎㅎ
내용은 깊은복사와 얕은 복사에 대한 이야기이다.
여기 a = [0, 1, 2, 3, 4, 5] 가 있다
이 값을 b 라는 변수에 넣어주고 프린트를 해본다면,
a = [0, 1, 2, 3, 4, 5]
b = a
print(a) # [0, 1, 2, 3, 4, 5]
print(b) # [0, 1, 2, 3, 4, 5]
위와 같이 나올 것이다. 만약 b에 값을 넣고, a의 0을 100으로 바꿔본다면?
a = [0, 1, 2, 3, 4, 5]
b = a
a[0] = 100
print(a) # [100, 1, 2, 3, 4, 5]
print(b) # [100, 1, 2, 3, 4, 5]
이렇게 a만 값을 바꾸었는데, b도 함께 값이 바뀌게 된다.
이렇게 같은 리스트를 공유하게 되는 것을 얕은 복사라고 한다.
a와 b는 같은 리스트의 메모리 주소를 알고 있는 변수만 복사가 된 것이다.
그럼 공유된 값이 아닌 다른 값을 가지고 있게 하려면 어떻게 해주면 되나?
아래와 같이 하면 된다.
a = [0, 1, 2, 3, 4, 5]
b = a.copy()
a[0] = 100
print(a) # [100, 1, 2, 3, 4, 5]
print(b) # [0, 1, 2, 3, 4, 5]
이제 우리가 생각하던 방식대로 나왔다.
그리고 이렇게 독립적인 값을 갖게 복사를 해주는 경우를 깊은 복사라고 한다.
이렇게 되면 a와 b의 리스트들은 전혀 다른 메모리 공간에 할당되는 것이다.
2차원 배열의 경우 어떨까?
a = [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
b = a.copy()
a[0][0] = 100
print(a)
print(b)
// 두 결과 모두 아래와 같이 출력된다.
[[100, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
이 경우엔 copy()를 씀에도 불구하고 왜 얕은 복사가 되었을까?
이유는 바로 리스트의 모든 깊이의 값을 복사하는 것이 아닌 최상위의 포인팅하는 값만 복사를 해주는 것이기 때문이다.
즉 2차원의 리스트 주소를 포인팅하고 있는 변수만 복사된 것이기 때문이다.
이를 해결하기 위해서는 아래와 같이 2가지의 방법이 있다.
1. copy 모듈을 활용한 깊은 복사를 사용하기
2. b의 모든 값에 a의 값 직접 대입하는 방법 (리스트를 대입할때와 달리 값을 직접 넣으면 새로운 값이 할당된다)
# 1번 방법
import copy
a = [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
b = copy.deepcopy(a)
a[0][0] = 100
print(a) # [[100, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
print(b) # [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
# 2번 방법
a = [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
b = [[0 for i in range(6)] for _ in range(2)]
for i in range(2):
for j in range(6):
b[i][j] = a[i][j]
a[0][0] = 100
print(a) # [[100, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
print(b) # [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
이렇게 지금 내가 얕은 복사를 사용하고 있는지 깊은 복사를 사용하고 있는지 자세히 파악하고 있는 것은
예기치 못한 결과가 나왔을 때 빠르게 판단할 수 있는 도움을 준다 ㅎ
'알고리즘 공부' 카테고리의 다른 글
Greedy라는 방법론 (0) | 2024.03.19 |
---|---|
중등수학으로 2차원 배열 방향 전환 이해하기 (3) | 2024.01.03 |