문제

내가 읽고 있어요 컴퓨터 과학자처럼 생각하는 방법 "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을 만들어 목록에 추가합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top