곱하기 운영자가 목록에 적용 (데이터 구조)
-
13-09-2019 - |
문제
내가 읽고 있어요 컴퓨터 과학자처럼 생각하는 방법 "Python Programming"에 대한 소개 텍스트입니다.
Multiply 연산자의 동작을 명확히하고 싶습니다 (*
) 목록에 적용되는 경우.
기능을 고려하십시오 make_matrix
def make_matrix(rows, columns):
"""
>>> make_matrix(4, 2)
[[0, 0], [0, 0], [0, 0], [0, 0]]
>>> m = make_matrix(4, 2)
>>> m[1][1] = 7
>>> m
[[0, 0], [0, 7], [0, 0], [0, 0]]
"""
return [[0] * columns] * rows
실제 출력은입니다
[[0, 7], [0, 7], [0, 7], [0, 7]]
올바른 버전 make_matrix 이다 :
def make_matrix(rows, columns):
"""
>>> make_matrix(3, 5)
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
>>> make_matrix(4, 2)
[[0, 0], [0, 0], [0, 0], [0, 0]]
>>> m = make_matrix(4, 2)
>>> m[1][1] = 7
>>> m
[[0, 0], [0, 7], [0, 0], [0, 0]]
"""
matrix = []
for row in range(rows):
matrix += [[0] * columns]
return matrix
첫 번째 버전의 이유 make_matrix 실패 (9.8의 책에 설명 된 바와 같이)는
... 각 행은 다른 행의 별칭입니다 ...
왜 그런지 궁금합니다
[[0] * columns] * rows
원인 ... 각 행은 다른 행의 별칭입니다 ...
하지만
[[0] * columns]
즉 왜 왜 [0]
행에서 다른 행 요소의 별칭이 아닙니다.
해결책
파이썬의 모든 것은 객체이며, 설명이 요구하지 않는 한 파이썬은 결코 사본을 만들지 않습니다.
당신이 할 때
innerList = [0] * 10
10 개의 요소가있는 목록을 만듭니다. 그들 모두는 같은 것을 언급합니다 int
물체 0
.
정수 객체가 있기 때문에 불변, 당신이 할 때
innerList[1] = 15
목록의 두 번째 요소를 변경하여 다른 정수를 나타냅니다. 15
. 그것은 항상 작동합니다 int
불변성.
그것이 이유입니다
outerList = innerList * 5
a list
5 개의 요소가있는 객체, 각 요소는 똑같다 innerList
위와 같이. 하지만 그때부터 list
물체는 변하기 쉬운:
outerList[2].append('something')
와 같다:
innerList.append('something')
그것들은 두 가지 언급이기 때문입니다 같은 list
물체. 요소는 그 단일로 끝납니다 list
. 복제 된 것으로 보이지만 사실은 하나만 있다는 것입니다. list
대상과 많은 언급.
대조적으로
outerList[1] = outerList[1] + ['something']
여기 있어요 창조 또 다른 list
물체 (사용 +
목록이있는 명시 적 사본이 있습니다). outerList
. 이 방법으로 요소를 "추가"하는 경우 (실제로 추가되지 않고 다른 목록을 작성), innerList
영향을받지 않습니다.
다른 팁
목록은 프리미티브가 아니며 참조로 전달됩니다. 목록의 사본은 목록에 대한 포인터입니다 (C 전문가). 목록에하는 모든 일은 목록의 모든 사본과 얕은 사본을하지 않는 한 내용의 사본에서 발생합니다.
[[0] * columns] * rows
죄송합니다. 방금 [0]에 큰 포인터 목록을 만들었습니다. 하나를 바꾸면 모두 변경하십시오.
정수는 참조별로 전달되지 않으므로 실제로 복사되므로 [0] * 내용은 실제로 많은 새로운 0을 만들어 목록에 추가합니다.