質問

私が読んでいる「Pythonプログラミング」の入門テキストですコンピューター科学者のように考える方法ます。

私はリストに適用される乗算演算子(*)の振る舞いを明確にしたい。

機能を考えるの 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]は、他の行の要素の別名ではない。

役に立ちましたか?

解決

Pythonですべてがオブジェクトであり、明示的にそうするように頼まない限り、Pythonはコピーを作ることはありません。

あなたが行うと

innerList = [0] * 10

あなたは10個の要素を持つリストを作成し、を同じintオブジェクトへの参照のうえ、それらのすべての0 の。

整数オブジェクトであるための不変のを、あなたが行うとき、

innerList[1] = 15
それは15 の別の整数を参照するように、

あなたは、リストの2番目の要素を変更しています。それは常にための作品int のオブジェクト不変ます。

これは、理由

outerList = innerList * 5

は、それぞれ一つの同じlistちょうど上記のようにするへの参照であり、5つの要素を持つinnerListオブジェクトを作成します。しかしlistオブジェクトであるため、を変更可能な

outerList[2].append('something')

と同じです

innerList.append('something')

彼らはを同じlistオブジェクトのへの2つの参照であるため。だから、要素は、その単一listで終わります。重複しているように見えるが、実際は一つだけlistオブジェクトが存在するということであり、それには多くの言及ます。

これとは対照的に、あなたがしなければ、

outerList[1] = outerList[1] + ['something']

ここでは、の(リストをlistを使用する明示的なコピーである) +オブジェクトの作成、及びouterListの第2の位置にそれへの参照を割り当てます。あなたはこの方法(実際に追加するが、別のリストを作成していない)の要素を「追加」した場合、innerListは影響を受けません。

他のヒント

リストは、彼らが参照によって渡され、プリミティブではありません。リストのコピー(C用語で)リストへのポインタです。あなたは浅いコピーを行う場合を除き、あなたがリストにやるものは、リストのすべてのコピーとその内容のコピーに起こります。

[[0] * columns] * rows

おっと、私たちは[0]へのポインタの大きなリストを作りました。 1を変更し、あなたがそれらすべてを変えています。

整数が参照によって渡されていない、彼らは本当にそれゆえ[0] *内容は本当にNEW 0年代の多くを作り、リストに追加され、コピーされます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top