python - पायथन सूची टुकड़ा वाक्यविन्यास किसी स्पष्ट कारण के लिए उपयोग किया जाता है




list shallow-copy (4)

मैं कभी-कभी पाइथन कोड में उपयोग की गई सूची स्लाइस सिंटैक्स को इस तरह देखता हूं:

newList = oldList[:]

निश्चित रूप से यह वही है जैसा कि:

newList = oldList

या क्या मैं कुछ न कुछ भूल रहा हूं?


एनएक्ससी की तरह, पाइथन वैरिएबल नाम वास्तव में किसी ऑब्जेक्ट को इंगित करते हैं, न कि स्मृति में एक विशिष्ट स्थान।

newList = oldList दो अलग-अलग चर बनाएगा जो एक ही ऑब्जेक्ट को इंगित करते हैं, इसलिए, oldList बदलना भी नई सूची बदल newList

हालांकि, जब आप नई सूची newList = oldList[:] , तो यह सूची "स्लाइस" करता है, और एक नई सूची बनाता है। [:] लिए डिफ़ॉल्ट मान 0 हैं और सूची का अंत है, इसलिए यह सब कुछ कॉपी करता है। इसलिए, यह पहले एक में निहित सभी डेटा के साथ एक नई सूची बनाता है, लेकिन दोनों को बदलने के बिना दोनों को बदला जा सकता है।


कभी नहीं सोचें कि पायथन में 'ए = बी' का मतलब है 'प्रतिलिपि बी को'। यदि दोनों तरफ चर हैं, तो आप वास्तव में यह नहीं जान सकते हैं। इसके बजाए, इसके बारे में सोचें 'अतिरिक्त नाम दें'।

यदि बी एक अपरिवर्तनीय वस्तु है (जैसे संख्या, टुपल या स्ट्रिंग), तो हां, प्रभाव यह है कि आपको एक प्रति प्राप्त होती है। लेकिन ऐसा इसलिए है क्योंकि जब आप अपरिवर्तनीय से निपटते हैं (जिसे शायद केवल पढ़ने , अपरिवर्तनीय या वर्म कहा जाता है) तो आपको परिभाषा के अनुसार हमेशा एक प्रति प्राप्त होती है।

यदि बी एक उत्परिवर्तनीय है, तो आपको यह सुनिश्चित करने के लिए हमेशा कुछ अतिरिक्त करना होगा कि आपके पास एक वास्तविक प्रति हैहमेशा सूचियों के साथ, यह एक टुकड़ा के रूप में सरल है: ए = बी [:]।

उत्परिवर्तन भी यही कारण है कि यह:

def myfunction(mylist=[]): 
    pass

... जो कुछ भी आपको लगता है वह काफी नहीं करता है।

यदि आप सी-पृष्ठभूमि से हैं: '=' का क्या शेष है, हमेशा एक सूचक है। सभी चर हमेशा पॉइंटर्स होते हैं। यदि आप किसी सूची में चर डालते हैं: a = [b, c], आपने पॉइंटर्स को बी और सी द्वारा इंगित मूल्यों पर इंगित किया है। यदि आप एक [0] = डी सेट करते हैं, तो स्थिति 0 में पॉइंटर अब जो कुछ भी इंगित करता है उसे इंगित कर रहा है।

कॉपी-मॉड्यूल भी देखें: http://docs.python.org/library/copy.html


[:] शालो सूची सूची की प्रतिलिपि बनाते हैं, जिसमें सूची सूची की प्रतिलिपि होती है जिसमें मूल सूची सदस्यों के संदर्भ होते हैं। इसका मतलब है कि प्रतिलिपि पर संचालन मूल की संरचना को प्रभावित नहीं करता है। हालांकि, यदि आप सूची सदस्यों के लिए कुछ करते हैं, तो दोनों सूचियां अभी भी उन्हें संदर्भित करती हैं, इसलिए यदि सदस्यों को मूल के माध्यम से एक्सेस किया जाता है तो अपडेट दिखाए जाएंगे।

एक गहरी प्रतिलिपि सभी सूची सदस्यों की प्रतियां भी बनाती है।

नीचे कोड स्निपेट कार्रवाई में एक उथली प्रति दिखाता है।

# ================================================================
# === ShallowCopy.py =============================================
# ================================================================
#
class Foo:
    def __init__(self, data):
        self._data = data

aa = Foo ('aaa')
bb = Foo ('bbb')

# The initial list has two elements containing 'aaa' and 'bbb'
OldList = [aa,bb]
print OldList[0]._data

# The shallow copy makes a new list pointing to the old elements
NewList = OldList[:]
print NewList[0]._data

# Updating one of the elements through the new list sees the
# change reflected when you access that element through the
# old list.
NewList[0]._data = 'xxx'
print OldList[0]._data

# Updating the new list to point to something new is not reflected
# in the old list.
NewList[0] = Foo ('ccc')
print NewList[0]._data
print OldList[0]._data

इसे एक अजगर खोल में चलाना निम्नलिखित प्रतिलेख देता है। हम पुरानी वस्तुओं की प्रतियों के साथ बनाई जा रही सूची देख सकते हैं। ऑब्जेक्ट्स में से एक का पुराना सूची पुरानी सूची के माध्यम से संदर्भ द्वारा अपडेट किया जा सकता है, और ऑब्जेक्ट पुरानी सूची के माध्यम से एक्सेस होने पर अपडेट देखा जा सकता है। आखिरकार, नई सूची में एक संदर्भ बदलना पुरानी सूची में प्रतिबिंबित नहीं किया जा सकता है, क्योंकि नई सूची अब एक अलग वस्तु का जिक्र कर रही है।

>>> # ================================================================
... # === ShallowCopy.py =============================================
... # ================================================================
... #
... class Foo:
...     def __init__(self, data):
...         self._data = data
...
>>> aa = Foo ('aaa')
>>> bb = Foo ('bbb')
>>>
>>> # The initial list has two elements containing 'aaa' and 'bbb'
... OldList = [aa,bb]
>>> print OldList[0]._data
aaa
>>>
>>> # The shallow copy makes a new list pointing to the old elements
... NewList = OldList[:]
>>> print NewList[0]._data
aaa
>>>
>>> # Updating one of the elements through the new list sees the
... # change reflected when you access that element through the
... # old list.
... NewList[0]._data = 'xxx'
>>> print OldList[0]._data
xxx
>>>
>>> # Updating the new list to point to something new is not reflected
... # in the old list.
... NewList[0] = Foo ('ccc')
>>> print NewList[0]._data
ccc
>>> print OldList[0]._data
xxx

शालो कॉपी: (एक स्थान से दूसरे स्थान पर स्मृति की प्रतियां)

a = ['one','two','three']

b = a[:]

b[1] = 2

print id(a), a #Output: 1077248300 ['one', 'two', 'three']
print id(b), b #Output: 1077248908 ['one', 2, 'three']

गहरी प्रतिलिपि: (ऑब्जेक्ट संदर्भ प्रतियां)

a = ['one','two','three']

b = a

b[1] = 2


print id(a), a #Output: 1077248300 ['one', 2, 'three']
print id(b), b #Output: 1077248300 ['one', 2, 'three']






shallow-copy