작성
·
15
1
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
안녕하세요
def solution(l,k):
result = []
curr = []
def backtracking(start, curr):
if len(curr) == k:
result.append(curr[:])
return
for i in range(start, len(l)):
curr.append(i+1)
backtracking(i + 1, curr)
curr.pop()
backtracking(0, curr)
return result
위의 코드에서 if len(curr) == k: 안에 result.append(curr[:]) 대신 result.append(curr)을 넣으면 result = [[], [], [], [], [], []]와 같이 값이 제대로 추가가 안 되던데 무슨 차이가 있는 건가요?
main 함수에서
test1 = []
test2 = [1,2,3]
test1.append(test2)
print(test1)
test1 = []
test1.append(test2[:])
print(test1)
이와 같이 테스트를 해보면 두 프린트 결과 모두 [[1,2,3]]으로 동일하게 나오는데 위의 경우는 달라서 질문 드립니다.
답변 1
0
안녕하세요, 나상민님
문제의 핵심은 얕은 복사와 참조의 차이입니다.
• result.append(curr)를 사용하면, curr 리스트의 참조를 결과 리스트에 저장합니다.
따라서, 백트래킹 과정에서 curr의 내용이 바뀔 때마다 이미 추가된 모든 항목도 같이 변합니다.
• 반면에, result.append(curr[:])는 curr의 얕은 복사본을 만들어 저장합니다.
이렇게 하면 그 시점의 curr 값이 보존되어, 이후에 curr가 변경되더라도 복사본은 그대로 유지됩니다.
main 함수에서 test2와 test2[:]를 비교했을 때는, 둘 다 한 번만 추가되기 때문에 출력 결과가 같지만, 백트래킹처럼 curr을 여러 번 수정하는 경우에는 복사본을 만들어 저장해야 올바른 결과를 얻을 수 있습니다. test1에 추가를 다 하신 후에 test2 배열의 원소를 수정한 후 test1을 출력하면 차이점을 이해하시게 될 겁니다.
즉, 백트래킹에서는 재귀 호출 후 curr.pop()으로 원소를 제거하면서 curr의 상태가 계속 바뀌므로, 현재 상태를 보존하려면 반드시 복사본(curr[:])을 추가해야 합니다.