हमें पायथन (या किसी अपरिवर्तनीय डेटा प्रकार) में ट्यूपल्स की आवश्यकता क्यों है?


140

मैंने कई पायथन ट्यूटोरियल (एक में, के लिए डाइव इनटू पायथन), और पायथन ओन पर भाषा संदर्भ पढ़ा है - मैं नहीं देखता कि भाषा को ट्यूपल्स की आवश्यकता क्यों है।

किसी सूची या सेट की तुलना में ट्यूपल्स की कोई विधि नहीं है, और अगर मुझे उन्हें सॉर्ट करने में सक्षम होने के लिए एक सेट या सूची में एक ट्यूपल को बदलना होगा, तो पहली जगह में एक ट्यूपल का उपयोग करने का क्या मतलब है?

अचल स्थिति?

जब कोई मूल रूप से आवंटित किया गया था, तो उसकी तुलना में कोई चर स्मृति में किसी भिन्न स्थान पर क्यों रहता है? पायथन में अपरिवर्तनीयता के इस पूरे कारोबार पर जोर दिया जा रहा है।

C / C ++ में यदि मैं एक पॉइंटर आवंटित करता हूं और कुछ वैध मेमोरी को इंगित करता हूं, तो मुझे परवाह नहीं है कि पता जहां तक ​​है, जब तक मैं इसे उपयोग करने से पहले यह शून्य नहीं है।

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

पायथन में, जब मैं एक स्ट्रिंग (या टुपल) आवंटित करता हूं, तो इसे एक्स को असाइन करें, फिर स्ट्रिंग को संशोधित करें, अगर यह मूल वस्तु है तो मुझे क्यों परवाह है? जब तक चर मेरे डेटा को इंगित करता है, तब तक यह सब मायने रखता है।

>>> x='hello'
>>> id(x)
1234567
>>> x='good bye'
>>> id(x)
5432167

x अभी भी मेरे द्वारा वांछित डेटा का संदर्भ है, किसी को इसकी आईडी या समान होने पर देखभाल करने की आवश्यकता क्यों है?


12
आप परिवर्तनशीलता के गलत पहलू पर ध्यान दे रहे हैं: "क्या आईडी समान है या अलग है" सिर्फ एक साइड इफेक्ट है; "क्या डेटा अन्य संदर्भों द्वारा इंगित किया गया है जो पहले उसी वस्तु को इंगित करता है जो अब अपडेट दर्शाते हैं" महत्वपूर्ण है।
चार्ल्स डफी

जवाबों:


124
  1. अपरिवर्तनीय वस्तुएँ पर्याप्त अनुकूलन की अनुमति दे सकती हैं; यह संभवतः इसलिए है कि तार जावा में भी अपरिवर्तनीय हैं, काफी अलग से विकसित किए गए हैं, लेकिन पायथन के रूप में एक ही समय के बारे में, और बस के बारे में सब कुछ वास्तव में कार्यात्मक भाषाओं में अपरिवर्तनीय है।

  2. विशेष रूप से पाइथन में, केवल अपरिवर्तनीय हैशेबल (और इसलिए, सेट के सदस्य, या शब्दकोशों में कुंजी) हो सकते हैं। फिर से, यह अनुकूलन को बर्दाश्त करता है, लेकिन अभी तक "पर्याप्त" से अधिक है (पूरी तरह से उत्परिवर्तित वस्तुओं को संग्रहीत करने वाले सभ्य हैश तालिकाओं को डिजाइन करना एक बुरा सपना है - या तो आप हर चीज की प्रतियां लेते हैं जैसे ही आप इसे हैश करते हैं, या यह जाँचने का दुःस्वप्न कि वस्तु का हैश है या नहीं जब से आपने पिछली बार इसका संदर्भ लिया है तब से इसका बदसूरत सिर रिसता है)।

अनुकूलन समस्या का उदाहरण:

$ python -mtimeit '["fee", "fie", "fo", "fum"]'
1000000 loops, best of 3: 0.432 usec per loop
$ python -mtimeit '("fee", "fie", "fo", "fum")'
10000000 loops, best of 3: 0.0563 usec per loop

11
@musicfreak, संपादित करें देखें मैंने अभी-अभी कहाँ किया है जहाँ एक tuple का निर्माण समतुल्य सूची के निर्माण की तुलना में 7.6 गुना अधिक तेज है - अब आप यह नहीं कह सकते कि आपने "कभी ध्यान देने योग्य अंतर नहीं देखा" किसी भी अधिक, जब तक कि आपकी "ध्यान देने योग्य" की परिभाषा नहीं। " सही मायने में अजीब है ...
एलेक्स मार्टेली

11
@musicfreak मुझे लगता है कि आप "समय से पहले अनुकूलन सभी बुराई की जड़" का दुरुपयोग कर रहे हैं। एक आवेदन में समय से पहले अनुकूलन करने के बीच एक बड़ा अंतर है (उदाहरण के लिए, "ट्यूपल्स सूचियों की तुलना में तेज़ हैं, इसलिए हम सभी ऐप में केवल टुपल्स का उपयोग करने जा रहे हैं!) और बेंचमार्क कर रहे हैं। एलेक्स का बेंचमार्क आनंददायक है और यह जानना कि एक सूची बनाने से ज्यादा तेजी है एक सूची बनाने में जो हमें भविष्य के अनुकूलन कार्यों में मदद कर सकती है (जब वास्तव में इसकी आवश्यकता हो)।
विर्जिल डुप्रास

5
@ एलेक्स, "एक सूची बनाने" की तुलना में वास्तव में तेजी से एक टपल का निर्माण कर रहा है, या हम पायथन रनटाइम के परिणाम को देखते हुए टपल को देख रहे हैं? मुझे बाद का लगता है।
त्रिफलक

6
@ACoolie, यह पूरी तरह से randomकॉल का प्रभुत्व है (बस ऐसा करने की कोशिश करें, आप देखेंगे!), इसलिए बहुत महत्वपूर्ण नहीं है। कोशिश करें python -mtimeit -s "x=23" "[x,x]"और आप सूची बनाने के लिए टपल बनाम बिल्डिंग के लिए 2-3 गुना अधिक सार्थक स्पीडअप देखेंगे।
एलेक्स मार्टेली

9
सोच रहे किसी के लिए - हम सूचियों से ट्यूपल्स पर स्विच करके एक घंटे से अधिक डेटा प्रोसेसिंग करने में सक्षम थे।
मार्क रिबाऊ जूल

42

ऊपर दिए गए उत्तरों में से कोई भी ट्यूल बनाम सूची के वास्तविक मुद्दे को इंगित नहीं करता है, जो कि पायथन के लिए कई नए हैं जो पूरी तरह से समझ में नहीं आते हैं।

Tuples और सूचियाँ विभिन्न उद्देश्यों की पूर्ति करती हैं। सूचियाँ समरूप डेटा को संग्रहीत करती हैं। आपके पास इस तरह की एक सूची होनी चाहिए:

["Bob", "Joe", "John", "Sam"]

इसका कारण यह है कि सूचियों का एक सही उपयोग है, क्योंकि वे सभी समरूप प्रकार के डेटा हैं, विशेष रूप से, लोगों के नाम। लेकिन एक सूची इस तरह से लें:

["Billy", "Bob", "Joe", 42]

उस सूची में एक व्यक्ति का पूरा नाम, और उनकी आयु है। यह एक प्रकार का डेटा नहीं है। उस जानकारी को संग्रहित करने का सही तरीका या तो टपल में है, या किसी ऑब्जेक्ट में। आओ हम कुछ कहते हैं:

[("Billy", "Bob", "Joe", 42), ("Robert", "", "Smith", 31)]

Tuples और Lists की अपरिवर्तनीयता और परिवर्तनशीलता मुख्य अंतर नहीं है। एक सूची एक ही तरह की वस्तुओं की एक सूची है: फाइलें, नाम, वस्तुएं। Tuples विभिन्न प्रकार की वस्तुओं का समूह है। उनके पास अलग-अलग उपयोग हैं, और कई पायथन कोडर्स के दुरुपयोग की सूची है जो ट्यूपल्स के लिए हैं।

कृपया नहीं।


संपादित करें:

मुझे लगता है कि यह ब्लॉग पोस्ट बताती है कि मुझे ऐसा क्यों लगता है कि मैंने इससे बेहतर काम किया है: http://news.e-scribe.com/397


13
मुझे लगता है कि आपके पास एक दृष्टि है जो कम से कम मेरे द्वारा सहमत नहीं है, दूसरों को नहीं जानते हैं।
स्टेफानो बोरीनी

13
मैं भी इस जवाब से पूरी तरह असहमत हूं। डेटा की एकरूपता का इस बात से कोई लेना-देना नहीं है कि आपको सूची या टपल का उपयोग करना चाहिए या नहीं। अजगर में कुछ भी इस भेद का सुझाव नहीं देता है।
ग्लेन मेनार्ड

14
गुइडो ने कुछ साल पहले इस बिंदु को बनाया था। aspn.activestate.com/ASPN/Mail/Message/python-list/1566320
जॉन ला

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

9
@ चलो, तुम मूल रूप से गलत हो। ट्यूपल्स के मुख्य उपयोगों में से एक डेटा के कई टुकड़ों को संग्रहीत करने के लिए एक समग्र डेटा प्रकार के रूप में है जो संबंधित हैं। तथ्य यह है कि आप एक ट्यूपल पर पुनरावृत्त कर सकते हैं और एक ही संचालन के कई प्रदर्शन इसे बदल नहीं सकते हैं। (जैसा कि संदर्भ मानते हैं कि कई अन्य भाषाओं में tuples में उनकी सूची समकक्षों के समान ही चलने योग्य विशेषताएं नहीं हैं)
एचएस।

22

अगर मैं उन्हें सेट करने के लिए एक सेट या सूची में एक टपल को परिवर्तित करना होगा, तो पहली जगह में एक टपल का उपयोग करने का क्या मतलब है?

इस विशेष मामले में, शायद एक बिंदु नहीं है। यह एक गैर-मुद्दा है, क्योंकि यह उन मामलों में से एक नहीं है जहां आप एक टुपल का उपयोग करने पर विचार करेंगे।

जैसा कि आप बताते हैं, टुपल्स अपरिवर्तनीय हैं। अपरिवर्तनीय प्रकार होने के कारण टुपल्स पर लागू होते हैं:

  • प्रतिलिपि दक्षता: एक अपरिवर्तनीय वस्तु की नकल करने के बजाय, आप इसे उपनाम दे सकते हैं (एक चर को एक संदर्भ में बाँध सकते हैं)
  • तुलना क्षमता: जब आप कॉपी-बाय-रेफरेंस का उपयोग कर रहे हैं, तो आप सामग्री के बजाय स्थान की तुलना करके दो चर की तुलना कर सकते हैं
  • इंटर्निंग: आपको किसी भी अपरिवर्तनीय मूल्य की अधिकतम एक प्रति को संग्रहीत करने की आवश्यकता है
  • समवर्ती कोड में अपरिवर्तनीय वस्तुओं तक पहुंच को सिंक्रनाइज़ करने की कोई आवश्यकता नहीं है
  • कब्ज की शुद्धता: कुछ मूल्यों को बदलने की अनुमति नहीं दी जानी चाहिए। यह (मेरे लिए) अपरिवर्तनीय प्रकारों का मुख्य कारण है।

ध्यान दें कि एक विशेष पायथन कार्यान्वयन उपरोक्त सभी सुविधाओं का उपयोग नहीं कर सकता है।

शब्दकोश कुंजियाँ अपरिवर्तनीय होनी चाहिए, अन्यथा कुंजी-ऑब्जेक्ट के गुणों को बदलना अंतर्निहित डेटा संरचना के अपरिवर्तकों को अमान्य कर सकता है। Tuples इस प्रकार संभावित रूप से कुंजी के रूप में उपयोग किया जा सकता है। यह सही शुद्धता का एक परिणाम है।

" इंट्रोड्यूसिंग ट्यूपल्स " भी देखें , डाइव इन पाइथन से


2
id ((1,2,3)) == id ((1,2,3)) गलत है। आप केवल स्थान की तुलना करके टुपल्स की तुलना नहीं कर सकते, क्योंकि इस बात की कोई गारंटी नहीं है कि उन्हें संदर्भ द्वारा कॉपी किया गया था।
ग्लेन मेनार्ड

@ ग्लेन: "जब आप कॉपी-बाय-रेफरेंस का उपयोग कर रहे हों" योग्यता टिप्पणी पर ध्यान दें। जबकि कोडर अपना स्वयं का कार्यान्वयन बना सकता है, टुपल्स के लिए प्रतिलिपि-दर-संदर्भ मोटे तौर पर दुभाषिया / संकलक के लिए एक मामला है। मैं ज्यादातर इस बात का जिक्र कर रहा था ==कि प्लेटफॉर्म स्तर पर कैसे लागू किया जाता है।
3

1
@Genn: यह भी ध्यान दें कि कॉपी-बाय-रेफरेंस tuples में लागू नहीं होता है (1,2,3) == (1,2,3)। यह और बात है।
आउटिस

जैसा कि मैंने स्पष्ट रूप से कहा, इस बात की कोई गारंटी नहीं है कि उन्हें संदर्भ द्वारा कॉपी किया गया था । टप्ल्स को पायथन में नजरबंद नहीं किया गया है; यह एक स्ट्रिंग अवधारणा है।
ग्लेन मेनार्ड

जैसा कि मैंने बहुत स्पष्ट रूप से कहा था: मैं प्रोग्रामर के बारे में बात नहीं कर रहा हूँ ट्यूल की तुलना लोकेशन से करते हुए। मैं उस संभावना के बारे में बात कर रहा हूं जो प्लेटफ़ॉर्म कर सकता है, जो प्रतिलिपि-दर-संदर्भ की गारंटी दे सकता है। इसके अलावा, इंटर्निंग किसी भी अपरिवर्तनीय प्रकार पर लागू किया जा सकता है, न केवल तार। मुख्य पायथन का कार्यान्वयन अपरिवर्तनीय प्रकारों को नजरअंदाज नहीं कर सकता है, लेकिन वास्तव में पायथन के पास अपरिवर्तनीय प्रकार हैं, जो इंटर्निंग को एक विकल्प बनाता है।
23

15

कभी-कभी हम वस्तुओं को शब्दकोश कुंजियों के रूप में उपयोग करना पसंद करते हैं

इसके लायक क्या है, हाल ही में ट्यूपल्स (2.6+) बढ़े index()और count()तरीके


5
+1: एक शब्दकोश कुंजी के रूप में एक उत्परिवर्तनीय सूची (या उत्परिवर्तित सेट या उत्परिवर्तनीय शब्दकोश) काम नहीं कर सकती है। इसलिए हमें अपरिवर्तनीय सूचियों ("ट्यूपल्स"), जमे हुए सेट और ... अच्छी तरह से ... एक जमे हुए शब्दकोश की आवश्यकता है, मुझे लगता है।
S.Lott

9

मैंने हमेशा एक ही मूल डेटा संरचना (सरणियों) के लिए दो पूरी तरह से अलग प्रकार के होने को पाया है जो एक अजीब डिजाइन है, लेकिन व्यवहार में वास्तविक समस्या नहीं है। (हर भाषा में इसके मौसा, पायथन शामिल हैं, लेकिन यह एक महत्वपूर्ण नहीं है।)

जब कोई मूल रूप से आवंटित किया गया था, तो उसकी तुलना में कोई चर स्मृति में किसी भिन्न स्थान पर क्यों रहता है? पायथन में अपरिवर्तनीयता के इस पूरे कारोबार पर जोर दिया जा रहा है।

ये अलग चीजें हैं। स्मरणशक्ति उस स्थान से संबंधित नहीं है जिसे स्मृति में संग्रहीत किया गया है; इसका मतलब है कि यह जो सामान है वह बदल नहीं सकता।

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

>>> x='hello'
>>> id(x)
1234567
>>> x='good bye'
>>> id(x)
5432167

यह परिवर्तनशील नहीं है ("उत्परिवर्तन") चर; यह एक ही नाम के साथ एक नया चर बना रहा है, और पुराने को त्याग रहा है। एक म्यूटिंग ऑपरेशन की तुलना करें:

>>> a = [1,2,3]
>>> id(a)
3084599212L
>>> a[1] = 5
>>> a
[1, 5, 3]
>>> id(a)
3084599212L

जैसा कि अन्य ने बताया है, यह शब्दकोशों की कुंजी के रूप में सरणियों का उपयोग करने की अनुमति देता है, और अन्य डेटा संरचनाएं जिन्हें अपरिवर्तनीयता की आवश्यकता होती है।

ध्यान दें कि शब्दकोशों के लिए कुंजियाँ पूरी तरह से अपरिवर्तनीय नहीं हैं। केवल एक महत्वपूर्ण के रूप में उपयोग किए जाने वाले हिस्से को अपरिवर्तनीय बनाने की आवश्यकता होती है; कुछ उपयोगों के लिए, यह एक महत्वपूर्ण अंतर है। उदाहरण के लिए, आपके पास उपयोगकर्ता का प्रतिनिधित्व करने वाला एक वर्ग हो सकता है, जो अद्वितीय उपयोगकर्ता नाम से समानता और हैश की तुलना करता है। तब आप अन्य उत्परिवर्तित डेटा को कक्षा में लटका सकते हैं - "उपयोगकर्ता लॉग इन है" आदि, क्योंकि यह समानता या हैश को प्रभावित नहीं करता है, यह संभव है और एक शब्दकोश में एक कुंजी के रूप में इसका उपयोग करने के लिए पूरी तरह से वैध है। यह अजगर में आमतौर पर जरूरत नहीं है; मैं अभी यह इंगित करता हूं क्योंकि कई लोगों ने दावा किया है कि चाबियों को "अपरिवर्तनीय" होने की आवश्यकता है, जो केवल आंशिक रूप से सही है। मैंने इसे कई बार C ++ मैप्स और सेट्स के साथ उपयोग किया है, हालाँकि।


>>> a = [1,2,3] >>> आईडी (ए) 3084599212L >>> एक [1] = 5 >>> एक [1, 5, 3] >>> आईडी (ए) 3084599212L आप ' ve ने केवल एक परिवर्तनशील डेटा प्रकार को संशोधित किया है, इसलिए यह मूल प्रश्न से संबंधित नहीं है। x = 'hello "id (x) 12345 x =" goodbye "id (x) 65432 कौन परवाह करता है कि यह एक नई वस्तु है या नहीं। जब तक x ने मेरे द्वारा असाइन किए गए डेटा को इंगित किया, तब तक यह सब मायने रखता है।
pyNewGuy

4
आपकी मदद करने की क्षमता से परे आप अच्छी तरह से भ्रमित हैं।
ग्लेन मेनार्ड

उप-प्रश्नों में भ्रम को इंगित करने के लिए +1, जो ट्यूपल्स के मूल्य को समझने में कठिनाई का मुख्य स्रोत प्रतीत होते हैं।
4

1
यदि मैं कर सकता हूं, तो यह बताने के लिए कि +1 सही है कि कुंजियों के लिए असली रूब्रिक हैचैबल ( docs.python.org/glossary.html#term-hashable ) है या नहीं ।
आउटिस

7

जैसा कि gnibbler ने एक टिप्पणी में पेश किया, गुइडो का एक मत था जो पूरी तरह से स्वीकार / सराहना नहीं है: "सूचियां सजातीय डेटा के लिए हैं, टपल्स विषम डेटा के लिए हैं"। बेशक, कई विरोधियों ने इसका अर्थ यह बताया कि किसी सूची के सभी तत्व एक ही प्रकार के होने चाहिए।

मैं इसे अलग तरह से देखना पसंद करता हूं, इसके विपरीत नहीं दूसरों के अतीत में भी:

blue= 0, 0, 255
alist= ["red", "green", blue]

ध्यान दें कि मैं एलिस्ट को सजातीय मानता हूं, भले ही टाइप (एलिस्ट [1])! = टाइप (एलिस्ट [2])।

यदि मैं तत्वों के क्रम को बदल सकता हूं और मेरे कोड में मुद्दे नहीं होंगे (मान्यताओं के अलावा, उदाहरण के लिए "इसे क्रमबद्ध किया जाना चाहिए"), तो एक सूची का उपयोग किया जाना चाहिए। यदि नहीं (जैसे कि blueऊपर के ट्यूल में ), तो मुझे एक टपल का उपयोग करना चाहिए।


अगर मैं 15 बार इस जवाब को वोट कर सकता था। यह वास्तव में मैं tuples के बारे में कैसा महसूस कर रहा हूँ।
पॉल

6

वे महत्वपूर्ण हैं क्योंकि वे फोन करने वाले को गारंटी देते हैं कि वे जिस वस्तु से गुजरते हैं, वह उत्परिवर्तित नहीं होगी। अगर तुम यह करते हो:

a = [1,1,1]
doWork(a)

फोन करने वाले का मूल्य की कोई गारंटी नहीं है एक कॉल के बाद। तथापि,

a = (1,1,1)
doWorK(a)

अब आप कॉलर के रूप में या इस कोड के एक पाठक के रूप में जानते हैं कि यह एक ही है। आप हमेशा इस परिदृश्य के लिए सूची की एक प्रति बना सकते हैं और पास कर सकते हैं, लेकिन अब आप एक भाषा निर्माण का उपयोग करने के बजाय चक्र बर्बाद कर रहे हैं जो अधिक अर्थपूर्ण अर्थ बनाता है।


1
यह टुपल्स की एक बहुत ही माध्यमिक संपत्ति है। ऐसे कई मामले हैं जहां आपके पास एक परिवर्तनशील वस्तु है जिसे आप किसी फ़ंक्शन में पास करना चाहते हैं और इसे संशोधित नहीं किया है, चाहे वह एक preexisting सूची या कुछ अन्य वर्ग हो। पाइथन (उदाहरण के लिए। कॉन्स्टिपल फू और सी ++ में) द्वारा "कॉन्स्टैप्ट पैरामीटर्स की कोई अवधारणा नहीं है।" ट्यूपल आपको यह देने के लिए होता है अगर ऐसा होता है कि एक टपल का उपयोग करना सुविधाजनक हो, लेकिन यदि आपको अपने कॉलर से एक सूची प्राप्त हुई है, तो क्या आप इसे कहीं और पास करने से पहले वास्तव में इसे टपल में बदलने जा रहे हैं?
ग्लेन मेनार्ड

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

a = [1,1,1] doWork (a) यदि dowork () को def dowork (arg) के रूप में परिभाषित किया गया है: arg = [0,0,0] dowork () को किसी सूची या ट्यूपल पर कॉल करने का परिणाम समान है
pyNewGuy


1

आपका प्रश्न (और अनुवर्ती टिप्पणियां) इस बात पर ध्यान केंद्रित करता है कि क्या आईडी () असाइनमेंट के दौरान बदलता है। अपरिवर्तनीय वस्तु प्रतिस्थापन और परिवर्तनशील वस्तु संशोधन के बीच अंतर के इस अनुवर्ती प्रभाव पर ध्यान केंद्रित करने के बजाय अंतर शायद सबसे अच्छा दृष्टिकोण नहीं है।

इससे पहले कि हम जारी रखें, सुनिश्चित करें कि नीचे दिया गया व्यवहार वही है जो आप पायथन से उम्मीद करते हैं।

>>> a1 = [1]
>>> a2 = a1
>>> print a2[0]
1
>>> a1[0] = 2
>>> print a2[0]
2

इस स्थिति में, a2 की सामग्री को बदल दिया गया था, भले ही केवल a1 को एक नया मान सौंपा गया था। निम्नलिखित के विपरीत:

>>> a1 = (1,)
>>> a2 = a1
>>> print a2[0]
1
>>> a1 = (2,)
>>> print a2[0]
1

इस बाद वाले मामले में, हमने इसकी सामग्री को अपडेट करने के बजाय पूरी सूची को बदल दिया। ट्यूपल्स जैसे अपरिवर्तनीय प्रकारों के साथ, यह केवल व्यवहार की अनुमति है।

यह बात क्यों है? मान लीजिए कि आपके पास एक तानाशाही है:

>>> t1 = (1,2)
>>> d1 = { t1 : 'three' }
>>> print d1
{(1,2): 'three'}
>>> t1[0] = 0  ## results in a TypeError, as tuples cannot be modified
>>> t1 = (2,3) ## creates a new tuple, does not modify the old one
>>> print d1   ## as seen here, the dict is still intact
{(1,2): 'three'}

टपल का उपयोग करते हुए, शब्दकोश इसकी कुंजियों को "इसके नीचे से परिवर्तित" होने से सुरक्षित रखता है, जो एक अलग मूल्य के लिए हैश करता है। कुशल कार्यान्वयन की अनुमति देने के लिए यह महत्वपूर्ण है।


जैसा कि दूसरों ने बताया है, अपरिवर्तनशीलता! सभी टुपल्स का उपयोग शब्दकोश कुंजियों के रूप में नहीं किया जा सकता है: {([1], [2]): 'मान'} विफल रहता है क्योंकि टपल में परिवर्तनशील सूचियों को बदला जा सकता है, लेकिन {(1), (2)): ' मान '} ठीक है।
नेड डिली

नेड, यह सच है, लेकिन मुझे यकीन नहीं है कि भेद जर्मेन को पूछे जाने वाले प्रश्न के लिए है।
चार्ल्स डफी

@ K.Nicholas, आपके द्वारा यहां संपादित किया गया कोड इस तरह से कोड को बदल देता है जैसे कि पूर्णांक निर्दिष्ट करने के लिए, टपल नहीं, बिल्कुल - बाद में अनुक्रमणिका संचालन विफल हो जाता है, इसलिए वे संभवतः परीक्षण नहीं कर सकते थे कि नया ट्रांसक्रिप्ट वास्तव में संभव था। सही ढंग से पहचानी गई समस्या, निश्चित रूप से; अवैध समाधान।
चार्ल्स डफी

@MichaelPuckettII, इसी तरह, ऊपर देखें।
चार्ल्स डफी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.