복붙노트

[PYTHON] 왜 파이썬에서 중첩 목록의 한 요소 만 변경할 수 없습니까? [duplicate]

PYTHON

왜 파이썬에서 중첩 목록의 한 요소 만 변경할 수 없습니까? [duplicate]

방금 Python에 이상한 것을 만났습니다.

>>> out=[[0]*3]*3
>>> out
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> out[0][1]
0
>>> out[0][1]=9
>>> out
[[0, 9, 0], [0, 9, 0], [0, 9, 0]]

음, 분명히 내가 원하는 건 :

[[0, 9, 0], [0, 0, 0], [0, 0, 0]]

이상하지 않은가? 저는 파이썬에 익숙하지 않지만 파이썬은 항상 직관적 인 행동으로 저를 감동시킵니다. 하지만 어떻게 이런 일이 생길까요? ... 그리고 내가 필요한 것을 어떻게 얻을 수 있습니까?

감사!

와트

해결법

  1. ==============================

    1.사실 이상한 행동이지만, * 연산자가 [0, 0, 0] 목록의 얕은 사본 인 경우에는 얕은 사본을 작성하기 때문입니다. id () 함수를 사용하여 이러한 내부 목록이 실제로 동일한 지 확인할 수 있습니다.

    사실 이상한 행동이지만, * 연산자가 [0, 0, 0] 목록의 얕은 사본 인 경우에는 얕은 사본을 작성하기 때문입니다. id () 함수를 사용하여 이러한 내부 목록이 실제로 동일한 지 확인할 수 있습니다.

    out=[[0]*3]*3
    id(out[0])
    >>> 140503648365240
    id(out[1])
    >>> 140503648365240
    id(out[2])
    >>> 140503648365240
    

    이해력은 다음과 같이 다른 목록을 작성하는 데 사용될 수 있습니다.

    out = [ [0]*3 for _ in range(3) ]
    
  2. ==============================

    2.*를 사용하여 목록의 요소를 복제하면 얕은 복사 작업이므로 변경할 수있는 객체가 포함 된 목록에서이 옵션을 사용하면 동일한 변경 가능한 객체에 대한 여러 참조로 끝납니다.

    *를 사용하여 목록의 요소를 복제하면 얕은 복사 작업이므로 변경할 수있는 객체가 포함 된 목록에서이 옵션을 사용하면 동일한 변경 가능한 객체에 대한 여러 참조로 끝납니다.

    대신 중첩 목록을 초기화하려면 다음을 사용하십시오.

    out = [[0]*3 for _ in range(3)]
    

    당신의 방법으로, out의 각 엔트리가 실제로 같은리스트에 대한 참조라는 것을 알 수 있습니다. 이것이 당신이하는 행동을 보는 이유입니다.

    >>> out = [[0]*3]*3
    >>> out[0] is out[1] is out[2]
    True
    
  3. from https://stackoverflow.com/questions/10941032/why-cant-i-change-only-a-single-element-in-a-nested-list-in-python by cc-by-sa and MIT license