반응형
질문
나는 리스트의 리스트를 만들었다:
>>> xs = [[1] * 4] * 3
>>> print(xs)
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
그리고 나서, 내부 값 중 하나를 변경했다:
>>> xs[0][0] = 5
>>> print(xs)
[[5, 1, 1, 1], [5, 1, 1, 1], [5, 1, 1, 1]]
왜 각 하위 리스트의 첫 번째 요소가 5
로 변경되었을까?
또한 참조:
어떻게 할당 후 예상치 못한 변경이 발생하지 않도록 리스트를 복제할 수 있나요? 문제에 대한 해결책
Python에서 빈 리스트의 사전을 초기화하는 방법은 무엇인가요? 리스트의 사전에 대한 유사한 문제
답변
[x]*3
을 작성하면 사실상 [x, x, x]
리스트를 얻습니다. 즉, 같은 x
에 대한 3개의 참조가있는 목록입니다. 그런 다음이 단일 x
를 수정하면 모든 세 참조를 통해 볼 수 있습니다 :
x = [1] * 4
xs = [x] * 3
print(f"id(x): {id(x)}")
# id(x): 140560897920048
print(
f"id(xs[0]): {id(xs[0])}\n"
f"id(xs[1]): {id(xs[1])}\n"
f"id(xs[2]): {id(xs[2])}"
)
# id(xs[0]): 140560897920048
# id(xs[1]): 140560897920048
# id(xs[2]): 140560897920048
x[0] = 42
print(f"x: {x}")
# x: [42, 1, 1, 1]
print(f"xs: {xs}")
# xs: [[42, 1, 1, 1], [42, 1, 1, 1], [42, 1, 1, 1]]
이를 수정하려면 각 위치에서 새 목록을 만드는지 확인해야합니다. 하나의 방법은 다음과 같습니다.
[[1]*4 for _ in range(3)]
이렇게하면 3 회마다 [1]*4
을 다시 평가하고 1 개의 목록을 3 개의 참조가 아닌 각 위치에서 새로 만듭니다.
리스트 내포가 수행되는 동안 요소 표현식을 매번 다시 평가합니다. [[1] * 4 for n in range(3)]
은 [x**2 for x in range(3)]
이 x**2
을 매번 다시 평가하는 이유와 동일한 이유로 매번 [1] * 4
을 다시 평가합니다. [1] * 4
의 모든 평가는 새로운 목록을 생성하므로 리스트 내포는 원하는 대로 작동합니다.
그와 별개로, [1] * 4
는 [1]
의 요소를 복사하지 않지만, 이는 무관합니다. 정수는 변경 불가능하기 때문에 1.value = 2
와 같은 작업을 수행하여 1을 2로 바꿀 수 없습니다.
반응형
댓글