CodingTest/Python Grammar Notes

[Python] 얕은 복사, 깊은 복사

조 수빈 2022. 7. 26. 17:05

🔍 얕은 복사, 깊은 복사

프로그래머스의 "가장 먼 노드" 라는 그래프 문제를 풀 때 겪은 일이다.
기존 리스트를 복사하여 새로운 리스트를 만들고, 새로운 리스트를 변경해줬는데 기존의 리스트도 같이 변경되었다.

image

(분명 id 값은 다른데..)

image

결론부터 이야기하자면,

위의 예시는 mutable 변수 내부에 mutable이 있는 케이스이고, 얕은 복사를 했을 경우 mutable 내부에 있는 mutable 객체들의 메모리 주소는 동일하다.

따라서 같은 객체를 참조하고 있는 상태이므로, 복사한 객체에서 변경을 해도 원본 객체에 영향을 준다.

image

id(a) 값과 id(b) 값은 다르지만, 그 내부의 객체 id(edge[0])과 id(re_edge[0])은 같은 주소임을 확인할 수 있다.

얕은 복사로는 변수간의 독립성이 보장되지 않는다!! => 깊은 복사를 사용해야 한다.


☁ mutable, immutable 객체

mutable 객체는 값이 변하는 가변객체를 말하며, immutable 객체는 값이 변하지 않는 불변객체를 말함

  • mutable: list, set, dict
  • immutable: bool, int, float, tuple, str, frozenset

immutable 객체는 값의 변경이 이루어지면 기존 객체 값을 수정하지 않고 새로운 객체를 생성함!!
하지만 mutable 객체의 경우, 값이 변경되어도 id가 변경되지 않으며 기존 객체 값을 수정함


☁ 얕은 복사

원본 객체의 주소값을 복사하는 방식, 원본 객체의 변경에 영향을 받음
immutable 객체는 상관없지만, mutable 객체를 복사하는 경우 주의가 필요함

방법: copy(), 슬라이싱[:]

import copy

a = [[1, 2]]

# 슬라이싱을 통한 얕은 복사
b = a[:]
# copy() 메서드를 통한 얕은 복사
c = copy.copy(a)

☁ 깊은 복사

주소값을 복사하는 방식이 아닌, 객체 자체를 복사하는 방식, 원본 객체와는 다른 새로운 객체

방법: deepcopy()

import copy

a = [[1, 2]]

# deepcopy() 메서드를 통한 깊은 복사
b = copy.deepcopy(a)

✅ 결론

immutable 객체의 경우 얕은 복사를 하더라도 괜찮다.
하지만 mutable 객체를 복사하는 경우 깊은 복사를 사용해야 한다!

참고로 처리속도는 슬라이싱 > copy() > deepcopy() 순으로 깊은 복사의 속도가 가장 느리다.
무작정 deepcopy()를 쓰는 것은 지양하고 상황에 맞게 사용하자!