2013-01-07 20 views
5

मैं पाइथन सीख रहा हूं और एक डेक बनाने की कोशिश कर रहा हूं। हालांकि, मुझे गलत आउटपुट मिलता है और मुझे यकीन नहीं है कि क्यों। इस प्रकार मेरे कोड है:पायथन डेक स्कोप?

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 सूची है, जिनमें से 4 विभिन्न स्थानों पर उन्हें में एक 0 के साथ एक कतार बनाना चाहते हैं, परिणाम मैं चाहता है :

([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

मैंने आपके कोड को सरल बनाकर पाइथन ट्यूटर पर visualization बनाया है। चारों ओर झुकाओ और आप आसानी से देख सकते हैं कि क्या हो रहा है।

आपके कोड में एक एकल पंक्ति परिवर्तन इसे ठीक कर सकता है।

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

उपरोक्त परिवर्तन का उपयोग करके visualization यहां दिया गया है।

4

आप Deque में एक वस्तु लगा रहे हैं, तो वस्तु बदलते। असल में, आप हमेशा एक ही ऑब्जेक्ट को डेक में डालते हैं, इसलिए सभी डेक एक ऑब्जेक्ट पी के संदर्भ हैं।

+0

और इस मुद्दे को हल करने के लिए आप ... करेंगे? –

+2

ऑब्जेक्ट की एक प्रति बनाएं- 'p [:] ', या यदि यह नहीं करता है, तो' प्रतिलिपि 'मॉड्यूल का उपयोग करके सूची का' गहरी कॉपी 'बनाएं, और उसके बाद सूची में * प्रतिलिपि * संलग्न करें। – Volatility

+0

धन्यवाद मुझे नहीं पता था कि मैं क्या देख रहा था लेकिन मैंने हल किया। 'पी [:] 'काम नहीं किया, लेकिन' deepcopy' किया था। तो अब यह दिखता है: 'newobj = copy.deepcopy (पी)' 'newobj [i] [j] = 0' ' init_q।संलग्न करें (newobj) ' – Sjieke

1

नेड Batchelder के जवाब देने के लिए मेरी टिप्पणी अप के बाद, आप निम्न तरीके से एक ही बात अपरिवर्तनीय कर सकता है: इस मामले में

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) 

जैसा कि मैंने कहा था, कभी-कभी यह चीजों को सरल बनाता है, कभी-कभी कम सरल ... लेकिन मुद्दा यह है कि इसके बारे में तर्क करना आसान है। आपको एस init_q में या तो list एस में list एस के भीतर कई list एस-इस बारे में चिंता करने की ज़रूरत नहीं है।

चाहे ट्रेडऑफ़ लायक है, वास्तव में यह मामला-दर-मामला निर्णय है, और शायद प्रत्येक प्रोग्रामर के लिए अलग है। इस मामले में, मैं अपरिवर्तनीय समाधान का उपयोग नहीं करता, और मुझे संदेह है कि कई अन्य (पायथन) प्रोग्रामर करेंगे। लेकिन यह जानने के लायक है कि इसे कैसे लिखना है।

आप 2 डी सूचियों के डेक के बजाय इसे 3 डी सूची के रूप में लिखने पर विचार कर सकते हैं और फिर इसे deque में खिला सकते हैं। यह स्पष्ट रूप से बराबर है, लेकिन धारणात्मक यह इस तरह से सोचने के लिए आसान हो सकता:

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) 

पुनश्च, अगर आप बात इस तरह का का एक बहुत कर रहे हैं, आप numpy पर एक नज़र डालें कर सकते हैं। यदि यह आपकी पूरी समस्या है, तो यह आपको कोई अच्छा काम नहीं करेगा ... लेकिन यदि आप बहु-आयामी सरणी के साथ कुछ और जटिल करते हैं, तो यह होगा।