2013-01-07 4 views
5

私はPythonを学んでおり、両端キューを作成しようとしています。しかし、私は間違った出力を得て、なぜ私は確信していません。異なる場所でそれらに0を持っている4そのうちこのコードでPython dequeスコープ?

p = [2, 1], [1, 1] 
init_q= deque() 

init_q.append(p) 
for i in range(len(p)): 
    for j in range(len(p[i])): 
     temp = p[i][j] 
     p[i][j] = 0 
     init_q.append(p) 
     p[i][j] = temp 

while init_q: 
    print init_q.pop() 

私はリストに取る、私はその後、5リストでキューを作成したい、私が欲しい結果がされています。私のコードは次のようです:

([2, 1], [1, 1]) 
([0, 1], [1, 1]) 
([2, 0], [1, 1]) 
([2, 1], [0, 1]) 
([2, 1], [1, 0]) 

しかし、私が得る結果は次のとおりです。

([2, 1], [1, 1]) 
([2, 1], [1, 1]) 
([2, 1], [1, 1]) 
([2, 1], [1, 1]) 
([2, 1], [1, 1]) 
+0

予想される出力が逆方向ではないと確信していますか? – abarnert

答えて

3

コードを簡略化してPython Tutorにvisualizationを作成しました。フィドルを回ると、何が起こっているのかを簡単に見ることができます。

コードを1行変更すればこれを修正できます。

init_q.append(map(list, p)) # Initialize a new list from p's element lists 

ここでは上記の変更を使用してvisualizationです。

4

あなたは、オブジェクトを変更し、両端キューにオブジェクトを入れています。実際には、常に同じオブジェクトを両端キューに入れます。したがって、両端キューはすべて1つのオブジェクトpへの参照です。ネッドBatchelderの答えに私のコメントをフォローアップ

+0

そしてこの問題を回避するには...? –

+2

オブジェクトのコピーを作成します - 'p [:]'が実行されない場合、 'copy'モジュールを使用してリストの' deepcopy'を作成し、* copy *をリストに追加してください。 – Volatility

+0

おかげで私は何を探しているのか分からなかったが解決した。 'p [:]'は動作しませんでしたが、 'deepcopy'は動作しました。だから今のようになります: 'newobj = copy.deepcopy(p)' 'newobj [i] [j] = 0' ' init_q。append(newobj) ' – Sjieke

1

は、ここにあなたがimmutably同じことを行うことができます方法は次のとおりです。この場合

for i in range(len(p)): 
    for j in range(len(p[i])): 
     temprow = [0 if y==j else p[i][y] for y in range(len(p[i]))] 
     temp = [temprow if x==i else p[x] for x in range(len(p))] 
     init_q.append(temp) 

、私は結果がたくさん読みにくく、彼の提案よりもあると思う:

 temp = copy.deepcopy(p) 
     temp[i][j] = 0 
     init_q.append(temp) 

私が言ったように、ときには物事が簡単になったり、時にはそれほど単純にならないこともあります...しかし、要点は理由が分かりやすいことです。 listinit_qに複数あるのか、それとも劣悪であるのか、listの中のサブlistが共有アイデンティティであるかどうかを心配する必要はありません。

トレードオフが価値あるかどうかは、実際にはケースバイケースの決定であり、プログラマごとに異なる可能性があります。この場合、私は不変の解決法を使用しないでしょう、そして私は他の多くの(Python)プログラマーが疑うことがあります。しかし、それを書く方法を知る価値があります。

2Dリストのデキュールの代わりに、dequeに3Dリストとして書き込むこともできます。これは明らかに同等だが、概念的には、この方法を考える方が簡単かもしれ:

init_q.append(p) 
q = [copy.deepcopy(p) for i in range(len(p)) for j in range(len(p[i]))] 
for i in range(len(p)): 
    for j in range(len(p[i])): 
     q[i*len(p[i])+j][i][j] = 0 
init_q.extend(q) 

PSあなたはこの種のものをたくさんやっている場合、あなたはnumpyを見てみたいことがあります。これがあなたの全面的な問題であれば、それはあなたに何の役にも立たないでしょう...しかし、多次元配列でもっと複雑なことをすれば、それは実現します。