TIL | 파이썬 기초 - 4

송치헌·2021년 7월 23일
0

TIL | 파이썬 기초

목록 보기
4/4

참고자료

https://wikidocs.net/16038

얕은 복사와 깊은 복사


얕은 복사(Shallow Copy)

>>> a = [1,2,3,4,5]
>>> b = a
>>> id(a)
140376986310528
>>> id(b)
140376986310528
>>> b[0] = 3
>>> print(a)
[3,2,3,4,5]

ba를 할당하면 값이 할당되는 것이 아니라 같은 메모리 주소를 갖게 됩니다.

따라서 a의 값을 가진 b를 따로 만들고 싶으면 리스트 a를 복사하여 b에 할당해 주어야 합니다.

그 중 얕은 복사의 방법 중 하나인 인덱싱이 있습니다.

>>> a = [1,2,3,4,5]
>>> b = a[:]
>>> id(a)
140377061076480
>>> id(b)
140376986448512

다음은 copy모듈을 사용하여 복사하는 방법입니다.

import copy

a = [1,2,3,4,5]
b = copy.copy(a)
print(id(a), id(b)) #139881387176320 139881387158080

그러나 두 복사 방법은 얕은 복사이기 때문에 리스트 안의 mutable한 객체(변경 가능한 객체)가 존재하면 그 객체 안에 있는 값을 수정하면 다른 값도 똑같이 수정됩니다.

이해가 쉽게 예를 들어보면,

import copy

a = [[1,2],[3,4]]
b = copy.copy(a)
b[0][0] = 5
print(a) #[[5, 2], [3, 4]]

a는 건들지 않았지만 b를 수정하니 a도 바뀌었습니다.

그 이유가 바로 리스트b에 존재하는 내부 리스트가 mutable하기 때문입니다. 그래도 이해가 안된다면 다음 예를 들어보겠습니다.

import copy

a = [9,[1,2,3,4]]
b = copy.copy(a)
b[0] = 5
print(a) #[9,[1,2,3,4]]
print(b) #[5,[1,2,3,4]]

여기서 b를 수정했음에도 a가 바뀌지 않은 이유는 b에서 수정하기 위해 접근한 객체 b[0](숫자 9) immutable한 객체이기 때문입니다.

mutable과 immutable

mutable은 변경 가능하다는 뜻으로 list, set, dictionary 등이 있습니다.

immutable은 변경 불가능하다는 뜻으로 int, float, bool, tuple 등이 있습니다.

'''
immutable한 객체는 값을 변경하면 참조하는 메모리 주소값도 
바뀌는 것을 볼 수 있습니다.
'''
a = 1
print(id(a)) #140164009412320
a = 2
print(id(a)) #140164009412352

'''
mutable한 객체는 값을 변경해도 주소값이 바뀌지 않는 것을
볼 수 있습니다.
'''
l = [1,2,3]
print(id(l)) #140163937159232
l.append(4)
print(id(l)) #140163937159232

immutable이 변경할 수 없다고 하는 것은 현재 그 변수의 메모리값을 그대로 가져가면서 값이 변경될 수 없다는 뜻입니다. 위에서 a = 1 이라고 한 뒤 다시 a = 2라고 하는 것은 새로운 객체로 변경되는 것입니다.

다시 돌아와서 copy모듈을 사용하거나 인덱싱으로 얕은 복사를 할 경우 리스트 내부에 있는 객체에 대해 immutable인지 mutable인지에 따라 값이 동시에 바뀔수도, 아닐 수도 있다는 뜻입니다.
immutable한 객체이면 동시에 바뀌지 않고 mutable한 객체면 둘 다 동시에 바뀝니다.


깊은 복사(Deep Copy)

깊은 복사는 얕은 복사와 마찬가지로 copy모듈을 사용하는데 이번에는 copy.copy(a)를 사용하는 것이 아니라 copy.deepcopy(a) 메소드를 사용하여 복사합니다.

import copy

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

b[0][0] = 5
print(a) #[[1,2,3],[4,5]]
print(b) #[[5,2,3],[4,5]]

c = copy.copy(a) 

c[0][0] = 8
print(a) #[[8,2,3],[4,5]]
print(c) #[[8,2,3],[4,5]]
profile
https://oraange.tistory.com/ 여기에도 많이 놀러와 주세요

0개의 댓글

관련 채용 정보