9
>>> CM = [[0 for _ in range(10)]] * 10
>>> CM    
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
>>> CM[0][0] = CM[0][0] + 1
>>> CM
[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

混同行列を作成しようとしていました。基本的に、(i、j)ペアの数が含まれます。最初にリストのリストを作成し、次に適切な変数をインクリメントしました。ただし、期待どおりに機能しませんでした。CM [i] [0]は、iのすべての値に対してインクリメントされました。

回避策を見つけました。

>>> CM = [[0 for _ in range(10)] for _ in range(10)]
>>> CM
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
>>> CM[0][0] = CM[0][0] + 1
>>> CM
[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

しかし、誰かが最初の方法が失敗した理由を説明できれば幸いです。

4

1 に答える 1

6
>>> CM = [[0 for _ in range(10)]] * 10

同じオブジェクトへの参照を10回コピーしています。これと同等です:

>>> x = [0 for _ in range(10)]
>>> CM = [x, x, x, x, x, x, x, x, x, x]

したがって、1つの要素を操作すると、副作用が発生します。あなたの回避策はエレガントで正しいです。

ノート:

これは、リストの要素がリスト(変更可能)であるために発生します。たとえば、不変の文字列の場合、同じ文字列が異なるリストで参照されていても、操作できないため、問題にはなりません。Pythonはメモリを浪費することを好みません(つまり、明示的に指示されていない限りdeepcopy)。したがって、リストをコピーすると、参照がコピーされるだけです。

于 2013-03-27T08:51:27.090 に答える