파이썬으로 순열 구현하기 게시물에서 함수 외부에서 선언한 리스트를 함수 내부에서 값을 추가하려고 시간을 많이 쓴 적이 있다.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)