티스토리 뷰

 

 

리스트 복사하기

 

변수는 객체를 담는 그릇이 아니라 객체를 가리키는 이름입니다. 따라서 변수를 다른 변수에 대입하면 두 변수는 같은 객체를 가리키게 됩니다. 다시 말해, 하나의 객체를 두 개의 이름이 가리키는 것이지 객체 자체가 두 개가 된 것은 아닙니다. 그렇기 때문에 불변형 객체immutable object에서는 한 변수에 새 데이터를 대입해도 다른 변수에 영향을 미치지 않지만, 리스트 같은 변형 객체mutable object에서는 그렇지 않습니다. 이는 장점이 되기도 하고, 단점이 되기도 합니다. 우선 여기까지 코드로 확인해 보겠습니다.

 

>>> mu_a = [2020, 'year']
>>> mu_b = mu_a
>>> mu_b.append(['hi', 'hello'])
>>> mu_a
[2020, 'year', ['hi', 'hello']]

 

얕은 복사

 

리스트는 변형 객체이므로 mu_b를 바꿔도 mu_a까지 바뀝니다. mu_a나 mu_b나 같은 변형 객체를 가리키고 있기 때문입니다. 하지만 이런 동작을 원하지 않을 때는 어떻게 해야 할까요? 객체 자체를 두 개로 복사하고, 이 둘을 각각 mu_a와 mu_b가 가리키게 할 수는 없을까요? 바로 이것이 얕은 복사shallow copy의 개념입니다. 리스트 메서드 가운데 copy()가 얕은 복사를 수행합니다. 다음 코드를 확인해 보겠습니다.

 

>>> mu_a = [2020, ['hi', 'hello']]
>>> mu_b = mu_a.copy()

 

여기서 mu_a와 mu_b는 하나의 객체를 가리키는 두 개의 이름이 아닙니다. id() 또는 is 연산자로 둘을 비교하면 False를 확인할 수 있습니다.

 

>>> mu_a is mu_b
False

 

하지만 요소들의 정체성은 같습니다.

 

>>> mu_a[0] is mu_b[0]
True
>>> mu_a[1] is mu_b[1]
True

 

그리고 mu_b를 바꾸더라도 mu_a는 그대로입니다. 바로 이것이 얕은 복사의 특징입니다.

 

>>> mu_b.append('year')
>>> mu_b
[2020, ['hi', 'hello'], 'year']
>>> mu_a
[2020, ['hi', 'hello']]

 

얕은 복사에는 한 가지 허점이 있습니다. 요소 자체의 정체성이 같기 때문에 요소가 변형 객체이면 변형 객체의 특성을 따른다는 것입니다. 다음 코드를 볼까요?

 

>>> mu_b[1][1] = 'bye'
>>> mu_b
[2020, ['hi', 'bye'], 'year']
>>> mu_a
[2020, ['hi', 'bye']]

 

mu_b[1]이 리스트라서 변형 객체이기 때문에 mu_b[1][1]을 바꾸었지만 mu_a[1][1]도 바뀐 겁니다.

 

 

 

깊은 복사

 

이를 보완한 복사가 깊은 복사deep copy입니다. 깊은 복사는 객체를 복사할 때 변형성을 따집니다. 불변형 객체는 정체성을 그대로 가져오고, 변형 객체는 새 위치에 새로 만드는 거죠. 따라서 어느 한쪽을 수정하더라도 다른 하나에 영향을 미치지 않습니다. 파이썬에서 깊은 복사는 copy 모듈의 deepcopy()가 담당합니다.

 

>>> import copy
>>> mu_a = [2020, ['hi', 'hello']]
>>> mu_b = copy.deepcopy(mu_a)
>>> mu_a is mu_b
False
>>> mu_a[0] is mu_b[0]
True
>>> mu_a[1] is mu_b[1]
False

 

불변형 객체는 변형될 수 없으니 정체성을 그대로 가져왔고, 변형 객체는 미연의 사고를 방지하기 위해 새로 만들어졌습니다. 다음 코드를 확인해 보세요.

 

>>> mu_b[1][1] = 'bye'
>>> mu_b
[2020, ['hi', 'bye']]
>>> mu_a
[2020, ['hi', 'hello']]

 

이렇듯 객체를 복사할 때는 깊은 복사를 수행해야 현실 세계의 복사와 같은 효과를 낼 수 있습니다. 하지만 세상 모든 것에는 장점이 있으면 단점도 있는 법, 깊은 복사에도 단점이 있습니다. 바로 비싸고 느리다는 겁니다. 비싸다는 것은 메모리 자원을 많이 소비한다는 뜻입니다. 물론 느리다는 것은 얕은 복사에 비해 그렇다는 거죠.

 

마지막으로 한마디 덧붙이자면, 파이썬에는 얕은 복사를 수행하는 함수가 별도로 제공됩니다. 눈치챘을지 모르겠지만 copy 모듈의 copy()입니다. list 모듈의 copy()는 말 그대로 리스트에만 사용할 수 있는 메서드지만, copy 모듈의 copy()와 deepcopy()는 객체에 사용할 수 있는 함수입니다.

 

 

댓글
댓글쓰기 폼
공지사항
Total
248,427
Today
802
Yesterday
1,065
링크
«   2022/10   »
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
글 보관함