2013-01-07 13 views
5

Python'u öğreniyorum ve bir deque yapmaya çalışıyorum. Ancak, yanlış çıktı alıyorum ve neden emin değilim. şöyle Benim kodudur:Python deque kapsamı?

Ben bir listede almak Bu kodda
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() 

, o zaman farklı yerlerde bunları bir 0, 4 olan 5 listesinde, bir sıra oluşturmak istiyorum, bunu istiyorum sonucudur :

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

Ancak, ben olsun sonucudur: Daha sonra nesneyi değiştirerek, deque bir nesne koyarak

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

Beklenen çıktının geriye doğru olmadığından emin misiniz? – abarnert

cevap

3

Kodunuzu basitleştirerek Python Tutor'da bir visualization oluşturdum. Etrafında dolaşın ve neler olduğunu kolayca görebilirsiniz.

Kodunuzdaki tek bir satır değişikliği bunu düzeltebilir.

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

Yukarıdaki değişikliği kullanarak visualization İşte.

4

. Aslında, her zaman aynı nesneyi deque içine sokarsınız, bu yüzden tüm deque, bir nesneye atıfta bulunur. Ned Batchelder cevabı benim yorumum

+0

Ve bu sorunu aşmak için ...? –

+2

Nesnenin bir kopyasını yapın - 'p [:]', ya da bu gerçekleşmiyorsa, 'copy' modülünü kullanarak listenin bir' deepcopy'unu yapın ve sonra * copy * 'ı listeye ekleyin. – Volatility

+0

Teşekkürler Ne aradığımı bilmiyordum ama çözdüm. 'p [:]' işe yaramadı, ama '' deepcopy'' yaptı. Yani şimdi benziyor: 'newobj = copy.deepcopy (p)' 'newobj [i] [j] = 0' ' init_q.adduck (newobj) ' – Sjieke

1

takibi, burada immutably aynı şeyi yapabileceğini nasıl:

: Bu durumda

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) 

, ben sonuç çok daha az okunabilir yaptığı öneri daha olduğunu düşünüyorum Söylediğim gibi, bazen işleri daha basit, bazen daha az basit hale getirir… Ama asıl mesele, akılda tutulması daha kolaydır.'un init_q adresinde birden fazla list s içerip içermediğine dair endişeniz olmasa da, list s kimliğinin alt kısmında list s kimlikleri paylaşılıyor.

Tradeoff'a değip değmeyeceği gerçekten durum başına bir karardır ve muhtemelen her programcı için farklıdır. Bu durumda, değişmez çözümü kullanmazdım ve diğer birçok (Python) programcıdan kuşkuluyum. Ama nasıl yazılacağını bilmeye değer.

Ayrıca, bunları 2B listelerinin deque yerine 3D bir liste olarak yazmayı ve daha sonra deque içine beslemeyi düşünebilirsiniz. Açıkçası eşdeğer, ama kavramsal olarak şekilde düşünmek basit olabilecek: Eğer bu tür şeyleri çok yaptığını eğer

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, sen numpy bakmak isteyebilirsiniz. Eğer bu senin bütün probleminse, sana hiç iyi gelmeyecek… ama çok boyutlu dizilerle daha karmaşık bir şey yaparsan, olacak.