언어/파이썬

참조와 사본의 차이 (S와 S[:] 의 차이)

AlgoPoolJa 2020. 12. 22. 19:05

최근 알고리즘을 풀 때 여러 케이스에서 list를 다뤘는데 헷갈리는 경우가 많아 정리해둔다. 

우선 해당 실험은 파이썬 3.8.3을 기준으로 진행했다. 

위의 코드와 같이 케이스는 4개로 구분했다. 

첫번째 케이스부터 한번 보자 

cmp = full

이 경우는 cmp에 full의 값 뿐만 아니라 주소도 full의 주소와 동일해진다.

그래서 cmp의 값이 바뀌는 것 뿐만 아니라 full의 값도 같이 바뀌게 된다. full의 형태가 바뀌면 cmp도 full의 주소를 참조(refer)하고 있기때문에 값이 바뀌게 된다.

1번 결과

 

cmp[:] = full

이제 2번 케이스의 경우 슬라이스([:])를 cmp의 앞에 해주었다. 이 경우는 값은 full과 동일하게 되지만 1번 케이스와 다르게 cmp의 주소는 연산전 cmp의 주소가 그대로 할당된다. "이런 연산을 어디서 해? 굳이 필요하나?" 라고 생각할 수있지만 공간복잡도가 O(1)인 경우에는 아주 요긴하게 사용된다. 

 

2번 케이스

 

따라서 여기서 cmp의 마지막 원소값을 바꿔준다고 하여도 full의 마지막 원소값은 바뀌지 않는다. 

 

cmp = full[:]

해당경우는 참조의 개념이 아닌 사본(copy)를 하는 경우에 해당한다. 얼핏보면 2번케이스와 동일해보이지만 그렇지 않다 왜냐하면 연산전의 cmp의 주소가 연산후 cmp의 주소와 다르기 때문이다. 

따라서 여기서 cmp와 full의 주소도 다르므로 cmp의 마지막 원소값을 바꾼다고 하여도 full의 원소값은 바뀌어 지지 않는다.

cmp[:] = full[:]

마지막 경우 2번케이스와 동일한 결과가 나온것을 확인할 수 있다. 

 

참조(주소가 같은경우)하는 경우와 값을 복사하는 경우 (주소값을 1개만 사용하는 경우,2개 사용하는 경우)를 list로 알아보았다.