[파이썬 초보] for 문에서 빈 딕셔너리 선언 위치 차이 (안 or 밖) 에 따라 결과가 달라지는 이유 질문

조회수 2115회

안녕하세요 파이썬 초보 입니다.

for 문으로 순차적으로 증가하는 딕셔너리 만든 후 하나의 리스트에 추가하려고 하는데요, 빈 딕셔너리 선언 위치 차이 (for 문 밖에서 할지, for 문 안에서 할지) 에 따라 결과과 달라져서, 왜 이런지 이해를 하려고 해도 잘 되지 않습니다. 누가 쉽게 설명해 주실 수 있을까요.

아래는 제가 만든 예시 이미지인데, In [8] 스크립트가 정상작동하고, In [7] 스크립트도 정상적으로 작동할 것 같은데, In [7] 에서는 가장 마지막 값만 반복적으로 입력되어, 이해가 잘 되지 않습니다.

In [7] 에서 for 문 밖에서 만든 b = { } 가 for 문이 작동하면서, b["순서"] = i 를 만들면서 바로 a.append 로 추가되고, 다시 i+1 로 순서가 돌 때 b["순서"] = i+1 딕셔너리를 만들고 다시 a.append 로 계속 업데이트식으로 추가 되지 않을까 생각했습니다.

고수님들의 고견 여쭙습니다.

이미지

1 답변

  • 7 에서는 b를 append 한 이후에, b의 내용을 바꾼 것이 계속 이전에 이미 append 된 것에도 영향을 미치고 있죠. 즉, a 에 b 를 append 했지만, 그 시점에서 바깥에 있는 b와 append 된 b의 관계가 지속되고 있습니다. 왜냐면, 동일한 b이기 때문입니다.

    반면에 8에서는 for 루프에서 b={} 라고, b 를 매번 다시 만들어 줍니다. b 라는 변수에는 매번 새로운 딕셔너리가 "생성"되어서, 이전에 append 한 이전의 b 와는 다른 것이 되고 있어요.

    >>> b = {}
    >>> a = []
    >>> for i in range(7):
        b['ㅇ'] = i
        a.append(dict(b))
    
    
    >>> a
    [{'ㅇ': 0}, {'ㅇ': 1}, {'ㅇ': 2}, {'ㅇ': 3}, {'ㅇ': 4}, {'ㅇ': 5}, {'ㅇ': 6}]
    

    이 예를 보면, b가 바깥에 선언되어 있기는 하지만, 질문자가 원하는 식으로 결과가 나왔을 것으로 생각합니다. 이번에는 왜 b 를 바꾸었는데, append 된 사전들에는 영향이 없는가 하면, append 할 때에, b를 복사해서, 다른 인스턴스를 하나 만들어 append 를 해 주었기 때문입니다.

    처음 파이썬을 접할 때 매우 헷갈리게 하는 부분인데, 정리하면, 파이썬에서 list, dict 와 같은 변경가능한 집합형변수(용어가 정확한지 모르겠는데...)를 인자로 함수를 호출하면, 내용까지 복사해서 함수로 넘어가는 게 아니라, 레퍼런스만 넘어가는 ( c의 포인터처럼 ) 방식으로 동작한다.

    헷갈리기는 하는데, 곰곰히 왜 그랬을까 하고 생각하면, 우선 집합형변수를 몽땅 복사하는 게 비싸니까 이런 구현이 나왔을 거라고 생각합니다.

    그래서 list, dict 등을 인자로 넘길 때에는, 필요할 때에는 복사해서 넘기면 된다... 그렇습니다.

    • 빠른 답변 정말 감사합니다. 어떤 개념인지 알겠습니다. 답변을 몇번이고 보면서 개념을 숙지 해야겠습니다. 감사합니다. ~! 알 수 없는 사용자 2020.12.24 15:06

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)