일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- EC2
- lambda
- MongoDB
- socket io
- git
- RDS
- wetube
- NeXT
- TypeScript
- Vue
- S3
- SSA
- 중급파이썬
- pandas
- docker
- 파이썬
- dict
- async
- Props
- react
- AWS
- node
- crud
- flask
- Class
- 카톡
- merge
- 채팅
- SAA
- 튜플
- Today
- Total
초보 개발자
3강 깊은 복사와 얕은 복사 본문
v1 == v2 변수 v1과 v2가 참조하는 객체의 내용이 같은가?
v1 is v2 변수 v1과 v2가 참조하는 객체는 동일 객체인가?
객체를 비교할 때 사용할 수 있는 두가지 연산자를 정리하면 위와 같다.
v1 == v2는 내용이 같으면 True이고
v1 is v2는 동등해야 한다
r1 = [1,2,3]
r2 = [1,2,3]
r1 is r2 # r1과 r2가 참조하는 객체는 같은 객체인가?
False
r1 == r2 # r1과 r2가 참조하는 객체에 담긴 값은 같은가?
True
is 연산이 True를 반환하는 상황은 다음과 같다.
r1 = [1,2,3]
r2 = r1 # r1이 참조하는 리스트에 r2라는 이름을 하나 더 붙임
r1 is r2
True
r1 = ['John',('man','USA'),[175,23]] #John은 미국남자로 175cm 23세
r2 = list(r1) # r1의 내용으로 새로운 리스트를 만듦
r1 is r2
False
r1[0] is r2[0] # r1과 r2의 'John'은 동일 객체인가?
True
r1[1] is r2[1] # r1과 r2의 ('man','USA')은 동일 객체인가?
True
r1[2] is r2[2] # r1과 r2의 [175,23]은 동일 객체인가?
True
list함수를 써서 복사를 하면 참조하고 있는 값 역시 복사 되는 것이아니라(문자열 객체, 튜플 객체, 리스트객체가 2개씩 생기는 것이 아님) 참조하고 있는 값은 그대로 있고 리스트 자체만 하나가 더 생성이 되고 같은 값을 참조하는 형식이다. 각 참조하는 객체들의 레퍼런스 카운트는 2가됨
어딘가에 저장이 되어있는 문자열 객체, 튜플 객체, 리스트 객체를 각 리스트의 요소들이 참조를 하고 있는 것이다.
따라서 불변하는 것은 상관이 없지만 변경이 가능한 리스트 객체같은 경우에는 값을 바꾸어 버리면 r1의 값도 바뀌어 버린다. r2에의 2번째 인덱스인 리스트 객체의 값을 아예 값을 바꾸면 (ex ) r2[2]=[185,23]) 새로운 리스트 객체가 생성이 되고 그걸 참조하지만, 단순히 값의 내용을 변경하면 (ex ) r2[2][0]=185) 애초에 r1도 같은 메모리를 참조하고 있기 때문에 r1마저 바뀌어 버린다.
불변하는 것은 참조복사를하고 변하는 것은 깊은복사를 통해서 새로운 객체를 만들어 참조시키게 하면 변해도 기존 원형은 변하지 않을 것이기 때문이다.
정리하자면 값의 변경이 불가능한 immutable 객체는 얕은 복사를 해도 문제가 되지 않는다. 그러나 값의 변경이 가능한 mutable객체는 얕은 복사가 문제가 될 수 있다.
이러한 복사를 얕은 복사라고 한다.
깊은 복사는 반대로 리스트가 참조하고 있는 대상이 있을 때에 그걸 통째로 복사한다.
리스트도 복사하고 리스트가 참조하는 객체까지 복사한다.
통째로 복사하는 것은 메모리에 부담이 된다. 참조만 복사한다는 것은 얼마나 성능적에서도 효율적인가
따라서 처음부터 아래와 같이 복사를 하면 된다.
이건 파이썬에서 deepcopy를 쓰면된다.
J2021 = ['John', ('man','USA'),[175,23]]
import copy #deepcopy 함수 호출 위해서 copy 모듈 import
J2022 = copy.deepcopy(J2021)
J2022[2][1] += 1
J2021
['John', ('man','USA'), [175,23]]
J2022
['John', ('man','USA'), [175,24]]
(J2021[0] is J2022[0]) and (J2021[1] is J2022[1]) # 얕은 복사 확인
True
J2021[2] is J2022[2] # 깊은 복사 확인
False
d1 = (1,2,3)
d2 = 'Please'
c1 = tuple(d1) # d1 기반으로 튜플 생성, 사실상 튜플 복사
c2 = str(d2) # d2 기반으로 문자열 생성, 사실상 문자역 복사
d1 is c1 # d1과 c1이 참조하는 대상이 같은 객체인가?
True
d2 is c2 # d2와 c2가 참조하는 대상이 같은 객체인가?
True
'Python > 윤성우 열혈 파이썬' 카테고리의 다른 글
6강 객체처럼 다뤄지는 함수 그리고 람다 (0) | 2021.12.16 |
---|---|
5강 lterable 객체와 lterator 객체 (0) | 2021.12.16 |
4강 리스트 컴프리헨션 (0) | 2021.12.15 |
2강 수정 가능한 객체와 수정 불가능한 객체 (0) | 2021.12.15 |
1강 레퍼런스 카운터, 가비지 컬렉션 (0) | 2021.12.15 |