python - टप्पल स्लाइसिंग एक नई वस्तु के रूप में स्लाइसिंग सूची के विपरीत नहीं लौटी




list tuples (3)

पायथन (2 और 3) में। जब भी हम सूची का उपयोग करते हुए स्लाइस करते हैं तो यह एक नई वस्तु देता है, जैसे:

l1 = [1,2,3,4]
print(id(l1))
l2 = l1[:]
print(id(l2))

उत्पादन

>>> 140344378384464
>>> 140344378387272

यदि एक ही चीज़ को टपल के साथ दोहराया जाता है, तो वही वस्तु वापस आ जाती है, जैसे:

t1 = (1,2,3,4)
t2 = t1[:]
print(id(t1))
print(id(t2))

उत्पादन

>>> 140344379214896
>>> 140344379214896

यह बहुत अच्छा होगा अगर कोई इस बारे में कुछ प्रकाश डाल सके कि ऐसा क्यों हो रहा है, मेरे पाइथन अनुभव के दौरान मैं इस धारणा के तहत था कि खाली स्लाइस एक नई वस्तु देता है।

मेरी समझ यह है कि यह उसी वस्तु को लौटा रहा है जैसे टुपल्स अपरिवर्तनीय हैं और इसकी एक नई प्रति बनाने का कोई मतलब नहीं है। लेकिन फिर, कहीं भी दस्तावेजों में इसका उल्लेख नहीं किया गया है।


इस बारे में निश्चित नहीं है, लेकिन ऐसा लगता है कि पायथन आपको नकल करने से बचने के लिए उसी वस्तु को एक नया पॉइंटर प्रदान करता है क्योंकि ट्यूपल्स समान हैं (और चूंकि ऑब्जेक्ट टपल है, यह अपरिवर्तनीय है)।


कार्यान्वयन अपरिवर्तनीय प्रकारों के लिए समान उदाहरणों को वापस करने के लिए स्वतंत्र हैं (सीपीथॉन में, आप कभी-कभी तार और पूर्णांक के लिए समान अनुकूलन देख सकते हैं)। चूंकि ऑब्जेक्ट को बदला नहीं जा सकता है, इसलिए उपयोगकर्ता कोड में ऐसा कुछ भी नहीं है जिसे यह ध्यान रखने की आवश्यकता है कि क्या यह एक अद्वितीय उदाहरण या मौजूदा उदाहरण के लिए एक और संदर्भ रखता है।

आप here C कोड में शॉर्ट-सर्किट पा सकते हैं।

static PyObject*
tuplesubscript(PyTupleObject* self, PyObject* item)
{
    ... /* note: irrelevant parts snipped out */
    if (start == 0 && step == 1 &&
                 slicelength == PyTuple_GET_SIZE(self) &&
                 PyTuple_CheckExact(self)) {
            Py_INCREF(self);          /* <--- increase reference count */
            return (PyObject *)self;  /* <--- return another pointer to same */
        }
    ...

यह एक कार्यान्वयन विवरण है, ध्यान दें कि pypy ऐसा नहीं करता है।


यह एक कार्यान्वयन विवरण है। क्योंकि सूचियाँ आपस में l1[:] हैं, l1[:] को एक प्रतिलिपि बनानी चाहिए , क्योंकि आप l1 को प्रभावित करने के लिए l2 परिवर्तन की अपेक्षा नहीं करेंगे।

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





cpython