[Python3] 얕은 복사 (함수에서 리스트 사용하기)

Song_Song·2021년 5월 6일
0

파이썬으로 순열 구현하기 게시물에서 함수 외부에서 선언한 리스트를 함수 내부에서 값을 추가하려고 시간을 많이 쓴 적이 있다.ans 리스트를 아무리 append 하여도 함수 밖에서 출력하면 빈값만 출력되는 현상이 있었다.

nums = [1, 2, 3, 4, 5]

answer_list = []

def combi(n, ans):
    if n == len(nums):
        answer_list.append(ans) // ans 리스트를 아무리 append 하여도 빈값만 복사되는...
        return
    ans.append(nums[n])
    combi(n + 1, ans)
    ans.pop()
    combi(n + 1, ans)

combi(0, [])
print(answer_list)

이는 ans의 value 값이 answer_list에 append 된 것이 아니라 ans의 주소값을 대입해 준 것이다. 그러니 함수 밖으로 나오면 값을 잃어버리는..

마치 Call by reference 같은 느낌이다.

파이썬은 기본적으로 Call by Assignment (Call by Object-reference)이다. 모든 값이 객체라는 뜻이다.

위와 같은 문제를 해결하기 위해서는 값을 '복사'해서 넣어야 한다.
가장 간단한 방법으로는 문자열 슬라이싱 [:]을 사용하여 얕은 복사를 하는 방법이다.

def combi(n, ans):
    if n == len(nums):
        answer_list.append(ans[:]) 
        return
    ans.append(nums[n])
    combi(n + 1, ans)
    ans.pop()
    combi(n + 1, ans)

혹은 copy 라이브러리의 copy(얕은 복사)나 deepcopy(깊은 복사)를 사용하면 된다.

import copy

def combi(n, ans):
    if n == len(nums):
    	temp = copy.copy(ans) # temp = copy.deepcopy(ans)
        answer_list.append(temp) 
        return
    ans.append(nums[n])
    combi(n + 1, ans)
    ans.pop()
    combi(n + 1, ans)
profile
성장을 위한 정리 블로그

0개의 댓글