인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

나상민님의 프로필 이미지

작성한 질문수

코딩테스트 [ ALL IN ONE ]

완전탐색 (7) - 구현 [부분집합]

list1.append(list2)와 list1.append(list2[:])의 차이가 무엇인가요?

작성

·

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[:])을 추가해야 합니다.