2017-08-22 4 views
1

私は最近Pythonは -

しかし
[[0, 0, 0, 0], 
[0, 0, 0, 0], 
[0, 0, 0, 0], 
[0, 0, 0, 0]] 

として配列aをインスタンス化

a = [[0] * 4] * 4 

を使用して4x4の定数(0の)配列をインスタンス化しようとしたユニークな要素の一定の配列を作成し、これはそうではありません配列のいずれかの要素を変更すると、すべての要素が変更されるため、一意の要素の配列を作成します。たとえば、次のように変更します。

変更

[[1, 0, 0, 0], 
[1, 0, 0, 0], 
[1, 0, 0, 0], 
[1, 0, 0, 0]] 

からa私はこれがなぜ起こるか私は理解して考える(リストのコピーがリストのポインタをコピーして、指定しない限り、などのintのとは異なり、別のコピーを作成していない)が、疑問に残っています:

NumPyなどの外部モジュールを使用せずに定数配列をインスタンシエートする簡単な方法がありますか?ユニークな要素は後で単純なa[i][j] = xアドレッシングで変更できますか?

答えて

1
a = [[0 for _ in xrange(4)] for _ in xrange(4)] 

それを行う必要があり、それだけで無料で別々のリストに

1

を作成します。ここで何が起こっているのですか? 1は最初

>>> a = [[0] * 4] * 4 

をするとき、人は4つの0要素を持つ1つのリスト[0] * 4を作成します。このリストをliと呼ぶことにしましょう。

[li] * 4を実行すると、実際に同じオブジェクトに4回参照するリストが作成されます。

>>> [id(el) for el in a] 
[8696976, 8696976, 8696976, 8696976] # in my case 

どこからエントリーワイズので

>>> a[0][0] = 1 
[[1, 0, 0, 0], 
[1, 0, 0, 0], 
[1, 0, 0, 0], 
[1, 0, 0, 0]] 

ソリューションは、リストの各要素は、本当にユニークであることを確実にするために、単純であるように割り当てるときに1を取得します(ないこと)好奇心の結果を参照してください。たとえば、行うこと

#Python2 
>>> a = map(lambda _: [0]*4, range(4)) 
#Python3 
>>> a = list(map(lambda _: [0]*4, range(4))) 
#Python2&3 
>>> a[0][0] = 1 
[[1, 0, 0, 0], 
[0, 0, 0, 0], 
[0, 0, 0, 0], 
[0, 0, 0, 0]]