3

Spyder IDE で次の python コードをテストしました。2次元配列を 0..31 からまでq増加する数として出力すると考えています。しかし、実際には q を次のように返します。q[0][0]q[3][7]

[[24, 25, 26, 27, 28, 29, 30, 31], [24, 25, 26, 27, 28, 29, 30, 31], [24, 25, 26, 27, 28, 29, 30, 31], [24, 25, 26, 27, 28, 29, 30, 31]]. 

コード:

q=[[0]*8]*4 
for i in range(4): 
    for j in range(8): 
        q[i][j] = 8*i+j 
print q

ここで何が起こっているか分かりますか?ステップバイステップでデバッグしました。これは、すべての行の更新が他のすべての行と同期することを示しており、他のプログラミング言語での私の経験とはまったく異なります。

4

3 に答える 3

4
q=[somelist]*4 

は、4 つの同一の項目を持つリスト list を作成しますsomelist。たとえば、同じオブジェクトq[0]を参照します。q[1]

したがって、ネストされた for ループq[i]では、 の値に関係なく、同じリストを参照していますi

修正するには:

q = [[0]*8 for _ in range(4)]

リスト内包表記は[0]*84 つの異なる回数を評価し、結果として 4 つの異なるリストになります。


この落とし穴の簡単なデモを次に示します。

In [14]: q=[[0]*8]*4

2 行目の最初の要素だけを更新していると思うかもしれません。

In [15]: q[1][0] = 100

しかし、実際にはすべての行の最初の要素を変更することになります:

In [16]: q
Out[16]: 
[[100, 0, 0, 0, 0, 0, 0, 0],
 [100, 0, 0, 0, 0, 0, 0, 0],
 [100, 0, 0, 0, 0, 0, 0, 0],
 [100, 0, 0, 0, 0, 0, 0, 0]]
于 2012-09-02T13:03:00.307 に答える
1

*説明したように、この問題は、同じオブジェクトへの参照をさらに作成するリストの操作が原因で発生します。あなたがすべきことは、追加を使用することです:

q=[]
for i in range(4): 
    q.append([])
    for j in range(8): 
        q[i].append(8*i+j)
print q 

[[0, 1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, 14, 15], [16, 17, 18, 19, 20, 21, 22、23]、[24、25、26、27、28、29、30、31]]

于 2012-09-02T13:22:08.223 に答える
0

l = [x]*8あなたが実際にlist8つのコピーではなく、同じへの8つの参照を作成しているようなことをするとき。

実際に8つのコピーを取得するには、使用する必要がありますl = [[x] for i in xrange(8)]

>>> x=[1,2,3]
>>> l=[x]*8
>>> l
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]
>>> l[0][0]=10
>>> l
[[10, 2, 3], [10, 2, 3], [10, 2, 3], [10, 2, 3], [10, 2, 3], [10, 2, 3], [10, 2, 3], [10, 2, 3]]
>>> l = [ [x] for i in xrange(8)]
>>> l
[[[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]]]
>>> l[0][0] = 1
>>> l
[[1], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]], [[10, 2, 3]]]
于 2012-09-02T13:05:08.320 に答える