본문 바로가기
파이썬(Python)

[Python] 할당과 복사 / 얕은 복사, 깊은 복사 (shallow copy, deep copy)

by KwonSoonBin 2023. 1. 31.

📍할당과 복사

할당과 복사는 비슷해보이지만 차이가 있다. 비교를 위해 먼저 리스트를 다른 변수에 할당해보자!

리스트 a를 b에 할당

a = [1, 2, 3]
b = a

리스트를 다른 변수에 할당하였으므로 리스트가 두개가 될 것 같지만 확인해보면 다음과 같이 리스트는 하나이다.

두 리스트를 연산자로 확인해보면 True가 나온다.

이름은 다르지만 사실은 같은 리스트

a is b 
-> True

따라서 b의 요소를 변경하면 a도 변경이 된다.

b의 1번 인덱스를 5로 변경

b[1] = 5
print(a)
-> [1, 5, 3]
print(b)
-> [1, 5, 3]

이해하기 쉽게 그림으로 확인해보면 다음과 같다.

다음은 복사를 해보자!
이번에도 똑같은 리스트를 할당이 아닌 복사를 해보면 다음과 같다.

a를 b로 복사

a = [1, 2, 3]
b = a.copy()

이번엔 어떻게 되었을까..?


오.. 뭔가 다르다
앞에서 나온 할당 그림과 비교했을 때 리스트가 각각 생긴 걸 확인할 수 있다.
정말 서로 다른 녀석인지 확인해봐야겠다.

a와 b를 연산자로 비교

a is b
-> False
a == b
-> True

a 와 b 는 엄연히 다른 객체이지만 a를 그대로 복사했기 때문에 리스트의 요소는 모두 같으므로 ==로 비교해보면 같다고 나온다.

그럼 리스트의 요소를 변경해주면 a == b 도 False 가 나오겠군

b의 요소 하나를 바꿔보기

b[1] = 5
print(a)
-> [1, 2, 3]
print(b)
-> [1, 5, 3]

리스트 b는 변경이 되었지만 a는 그대로이다.

할당을 하면 b의 요소를 변경하면 a도 똑같이 변경이 되었다. 하지만 복사를 하면 a에는 아무런 영향을 미치지 않았다. 그림을 보면 쉽게 이해된다.

📍얕은 복사(shallow copy)

먼저 예시부터 들어본다. copy라는 모듈에 있는 얕은 복사를 사용해보자!

import copy

a = [1, 2, [3, 4]]
b = copy.copy(a)

print(b)
-> [1, 2, [3, 4]]

출력 결과 제대로 복사가 되었다. 그러면 이번에는 b의 요소를 변경해보자.

b[0] = 5

print(b)
-> [5, 2, [3, 4]]
print(a)
-> [1, 2, [3, 4]]

확인해보면 b의 요소만 바뀌었고 a는 그대로이다.

이번에는 리스트 안에 있는 리스트의 요소를 변경해보자.

import copy

a = [1, 2, [3, 4]]
b = copy.copy(a)

b[2].append(5)

print(b)
-> [1, 2, [3, 4, 5]]
print(a)
-> [1, 2, [3, 4, 5]]

엥..? 이번엔 a도 변경되었다. 이유는 무엇일까??

그림을 보면 이해하기가 편하다.
먼저 처음에 복사해주었을 때의 그림이다.


0,1번 인덱스인 1과 2는 각각 리스트가 따로 생성되어 있다.
하지만 리스트안의 리스트인 [3, 4]는 할당했을 때처럼 같은 리스트를 갖게 된다.

따라서 첫 번째처럼 바깥 리스트의 요소를 변경하면 다음과 같이 되고,


두 번째처럼 리스트 안의 리스트의 요소를 바꿔주면 다음과 같이 되는 것이다.

결국엔 얕은 복사는 가장 바깥에 있는 껍질만 복사를 하는 것이다.
따라서 안쪽 요소들까지 복사를 하고 싶다면 깊은 복사를 해주어야 한다.

📍깊은 복사(deep copy)

깊은 복사 역시 copy 모듈에 있는 기능을 이용한다.

import copy

a = [1, 2, [3, 4]]
b = copy.deepcopy(a)

b[2].append(5)

print(b)
-> [1, 2, [3, 4, 5]]
print(a)
-> [1, 2, [3, 4]]

얕은 복사와는 다르게 깊은 복사에서는 a가 변경되지 않는 것을 확인할 수 있다.

그림으로 확인해보면 다음과 같다.

 

 

 

 

 

 

 

 

 

출처:
https://dojang.io/mod/page/view.php?id=2282
https://wikidocs.net/16038

https://velog.io/@kkamyang/Python-%EC%96%95%EC%9D%80-%EB%B3%B5%EC%82%AC-%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%AC-shallow-copy-deep-copy

 

댓글