2015-02-23 20 views
6

मैं पाइथन 3.4.1 का उपयोग कर रहा हूं।
एक ही सूची के लिए a=[1,2], अगर मैं इसकी एक प्रति बना देता हूं, b = a.copy() जब मैं b में आइटम बदलता हूं, तो यह a में आइटम नहीं बदलेगा।
हालांकि, जब मैं सूचियों की एक सूची (वास्तव में एक मैट्रिक्स) परिभाषित करता हूं a = [[1,2],[3,4]], जब मैं b = a.copy() असाइन करता हूं। b को सूचीबद्ध करने के लिए मैं क्या करता हूं वास्तव में a को प्रभावित करता है।
मैंने अपने पते की जांच की, वे अलग हैं।
क्या कोई मुझे बता सकता है क्यों?पायथन सूची की एक सूची कॉपी करें

ps: मैंने जो किया वह b[0][0] = x है, और इसमें आइटम भी बदला गया था।

+0

के संभावित डुप्लिकेट [कैसे क्लोन या अजगर में सूची की कॉपी के लिए? ] (http://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list-in-python) – aruisdante

उत्तर

5
copy मॉड्यूल के लिए डॉक्स से

:

उथले और गहरी नकल के बीच अंतर परिसर वस्तुओं (वस्तुओं है कि अन्य वस्तुओं होते हैं, सूची या वर्ग उदाहरणों की तरह) के लिए ही प्रासंगिक है:

  • एक उथली प्रतिलिपि एक नई यौगिक वस्तु बनाती है और फिर (यथासंभव संभव है) मूल में पाए गए वस्तुओं को संदर्भित करती है।
  • एक गहरी प्रतिलिपि एक नई यौगिक वस्तु बनाती है और फिर, संक्षेप में, मूल में पाए गए वस्तुओं की प्रतियों में प्रतियां डालती है।

जब आप नियमित रूप से copy.copy() आप एक उथले प्रतिलिपि प्रदर्शन कर रहे हैं कहते हैं। इसका अर्थ यह है कि सूची-सूची के मामले में, आपको बाहरी सूची की एक नई प्रति प्राप्त होगी, लेकिन इसमें मूल आंतरिक सूचियां इसके तत्वों के रूप में होंगी। इसके बजाय आपको copy.deepcopy() का उपयोग करना चाहिए, जो बाहरी और आंतरिक दोनों सूचियों की एक नई प्रतिलिपि बनाएगा।

कारण यह है कि आपने copy([1,2]) का उपयोग करने के अपने पहले उदाहरण के साथ यह नहीं देखा है कि int जैसे प्राइमेटिव अपरिवर्तनीय हैं, और इस प्रकार एक नया उदाहरण बनाये बिना अपना मूल्य बदलना असंभव है। यदि सूची की सामग्री बदले में म्यूटेबल ऑब्जेक्ट्स (जैसे सूचियां, या म्यूटेबल सदस्यों के साथ किसी उपयोगकर्ता द्वारा परिभाषित ऑब्जेक्ट) थी, तो उन ऑब्जेक्ट्स का कोई भी उत्परिवर्तन सूची की दोनों प्रतियों में देखा गया होगा।

+0

धन्यवाद!और प्रतिलिपि के बारे में एक और सवाल। क्या मुझे कक्षा की एक प्रति मिल सकती है? पेड़ वर्ग की तरह, क्या मुझे एक साधारण तरीके से कुछ पेड़ वस्तु टी 1 की एक प्रति प्राप्त हो सकती है? – jack

+0

हां, आप 'copy' मॉड्यूल का उपयोग किसी भी ऑब्जेक्ट पर कर सकते हैं जो '__copy__' और' __deepcopy__' विधियों को परिभाषित करता है। विशिष्टताओं के लिए मूल उत्तर में लिंक किए गए दस्तावेज़ देखें। दुख की बात नहीं है, पाइथन में 'प्री-डिफ़ाइंड' कॉपी ऑपरेशन नहीं है जैसे सी ++ जैसी भाषाओं में है (जो आम तौर पर एक अच्छी बात है, क्योंकि सी ++ के ऑटो-जेनरेटेड कॉपी-कन्स्ट्रक्टर अक्सर गैर-तुच्छ वर्ग के लिए गलत होता है)। – aruisdante

+0

@jack आप यह जांच सकते हैं कि जब आप [pythontutor.com] पर प्रतिलिपि विधि का उपयोग करते हैं तो क्या हो रहा है (http://www.pythontutor.com/visualize.html#code=a+%3D+%5B%5B1,+2% 5D, +% 5B3, 4% 5D% 5D% 0Ab +% 3 डी + a.copy()% 0Ab% 5B0% 5D% 5B0% 5D +% 3 डी + 9 और मोड = प्रदर्शन और मूल = ऑप्ट frontend.js और संचयी = false और heapPrimitives = false और textReferences = false प्रति & लिपि = 3 और rawInputLstJSON =% 5 ब% 5D और curInstr = 0)। आप वहां देखे गए सभी पॉइंटर्स देख सकते हैं। –

2

शायद इस तरह के रूप में एक सूची समझ:

new_list = [x[:] for x in old_list] 

... हालांकि अगर आपके मैट्रिक्स गहरी से एक परत कर रहे हैं, सूची समझ शायद सिर्फ deepcopy का उपयोग कर की तुलना में कम सुरुचिपूर्ण है।

संपादित करें - जैसा कि बताया गया है, एक उथली प्रतिलिपि में अभी भी सूची के अंदर वस्तुओं के संदर्भ होंगे। उदाहरण के लिए ...

>>> this = [1, 2] 
>>> that = [33, 44] 
>>> stuff = [this, that] 
>>> other = stuff[:] 
>>> other 
[[1, 2], [33, 44]] 
>>> other[0][0] = False 
>>> stuff 
[[False, 2], [33, 44]] #the same problem as before 
>>> this 
[False, 2]    #original list also changed 
>>> other = [x[:] for x in stuff] 
>>> other 
[[False, 2], [33, 44]] 
>>> other[0][0] = True 
>>> other 
[[True, 2], [33, 44]] 
>>> stuff 
[[False, 2], [33, 44]] #copied matrix is different 
>>> this 
[False, 2]    #original was unchanged by this assignment 
+1

यह एक अनौपचारिक पाठक के लिए बहुत कम स्पष्ट है कि यह 'प्रतिलिपि' से विधियों का उपयोग करने से क्या कर रहा है, हालांकि यह थोड़ा अधिक प्रदर्शनकारी है। – aruisdante

+0

निश्चित रूप से, वह है। लेकिन सूची की समझ सबसे अधिक पाइथोनिक है, इसलिए मुझे लगता है कि यह 'स्पष्ट' माना जाता है, और किसके लिए निर्भर करता है। किसी भी घटना में, यदि मैट्रिक्स बहुत घोंसला है तो मेरा सुझाव बहुत उपयोगी नहीं होगा, लेकिन एक आयाम के लिए मुझे नहीं लगता कि यह बहुत बुरा है –

-3

यह बहुत बस, बस यही काम है:

b = a 

उदाहरण:

>>> a = [1, 2, 3] 
>>> b = a 
>>> b.append(4) 
>>> b 
[1, 2, 3, 4] 
>>> a 
[1, 2, 3, 4] 
संबंधित मुद्दे