जवाबों:
यह एक गतिशील सरणी है । व्यावहारिक प्रमाण: अनुक्रमण (बेहद कम अंतरों के साथ निश्चित रूप से (0.0013 µsecs!)) सूचकांक की परवाह किए बिना एक ही समय लेता है:
...>python -m timeit --setup="x = [None]*1000" "x[500]"
10000000 loops, best of 3: 0.0579 usec per loop
...>python -m timeit --setup="x = [None]*1000" "x[0]"
10000000 loops, best of 3: 0.0566 usec per loop
मुझे आश्चर्य होगा कि अगर आयरनपाइथन या जाइथन ने लिस्टेड लिस्ट का इस्तेमाल किया - तो वे इस धारणा पर बनी कई व्यापक रूप से इस्तेमाल की जाने वाली लाइब्रेरियों के प्रदर्शन को बर्बाद कर देंगे कि लिस्ट डायनेमिक अरे हैं।
x=[None]*1000
, जिससे किसी भी संभावित सूची के उपयोग के अंतर को नापा जा सकता है। आपको इनिशियलाइज़ेशन को अलग करने की आवश्यकता है:-s "x=[None]*100" "x[0]"
सी कोड वास्तव में बहुत सरल है। एक मैक्रो का विस्तार करना और कुछ अप्रासंगिक टिप्पणियों को दूर करना, मूल संरचना में है listobject.h
, जो एक सूची को इस प्रकार परिभाषित करता है:
typedef struct {
PyObject_HEAD
Py_ssize_t ob_size;
/* Vector of pointers to list elements. list[0] is ob_item[0], etc. */
PyObject **ob_item;
/* ob_item contains space for 'allocated' elements. The number
* currently in use is ob_size.
* Invariants:
* 0 <= ob_size <= allocated
* len(list) == ob_size
* ob_item == NULL implies ob_size == allocated == 0
*/
Py_ssize_t allocated;
} PyListObject;
PyObject_HEAD
एक संदर्भ संख्या और एक प्रकार का पहचानकर्ता होता है। तो, यह एक वेक्टर / सरणी है जो समग्र है। पूर्ण होने पर ऐसी सारणी को आकार देने के लिए कोड listobject.c
। यह वास्तव में सरणी को दोगुना नहीं करता है, लेकिन आवंटित करके बढ़ता है
new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);
new_allocated += newsize;
क्षमता हर बार, जहां newsize
अनुरोधित आकार है (आवश्यक नहीं है allocated + 1
क्योंकि आप extend
तत्वों की एक मनमानी संख्या के बजाय append
'उन्हें एक से एक कर सकते हैं)।
अजगर अक्सर पूछे जाने वाले प्रश्न भी देखें ।
array
मॉड्यूल या न्यूमपी को प्राथमिकता दी जाएगी।
यह कार्यान्वयन पर निर्भर है, लेकिन IIRC:
ArrayList
इस प्रकार इन सभी में O (1) यादृच्छिक अभिगम होता है।
O(1)
सूची अनुक्रमण एक बहुत ही सामान्य और मान्य धारणा है, कोई भी कार्यान्वयन इसे तोड़ने की हिम्मत नहीं करेगा।
मैं लॉरेंट लूस के लेख "पायथन सूची कार्यान्वयन" का सुझाव दूंगा । मेरे लिए वास्तव में उपयोगी था क्योंकि लेखक बताता है कि कैसे सीपीथॉन में सूची को लागू किया गया है और इस उद्देश्य के लिए उत्कृष्ट आरेख का उपयोग करता है।
सूची ऑब्जेक्ट सी संरचना
CPython में एक सूची ऑब्जेक्ट को निम्न C संरचना द्वारा दर्शाया गया है।
ob_item
सूची तत्वों को संकेत की एक सूची है। आबंटित मेमोरी में आवंटित स्लॉट की संख्या है।typedef struct { PyObject_VAR_HEAD PyObject **ob_item; Py_ssize_t allocated; } PyListObject;
आवंटित स्लॉट और सूची के आकार के बीच अंतर को नोटिस करना महत्वपूर्ण है। एक सूची के आकार के समान ही है
len(l)
। आवंटित स्लॉट की संख्या वह है जो मेमोरी में आवंटित की गई है। अक्सर, आप देखेंगे कि आवंटित आकार से अधिक हो सकता है। यहrealloc
हर बार नए तत्वों को सूची में संलग्न करने की आवश्यकता से बचने के लिए है।
...
संलग्न
हम सूची में एक पूर्णांक संलग्न करते हैं
l.append(1)
:। क्या होता है?
हम एक और तत्व जोड़कर जारी रखने के लिए:
l.append(2)
।list_resize
n + 1 = 2 के साथ कहा जाता है, लेकिन क्योंकि आवंटित आकार 4 है, इसलिए अधिक मेमोरी आवंटित करने की आवश्यकता नहीं है। जब हम 2 अधिक पूर्णांकों जोड़ने एक ही बात होता है:l.append(3)
,l.append(4)
। निम्नलिखित आरेख से पता चलता है कि हमारे पास अब तक क्या है।
...
सम्मिलित करें
आइए स्थिति 1 पर एक नया पूर्णांक (5) डालें
l.insert(1,5)
और आंतरिक रूप से जो होता है उसे देखें।
...
पॉप
जब आप पिछले तत्व पॉप:
l.pop()
,listpop()
कहा जाता है।list_resize
अंदर बुलाया जाता हैlistpop()
और यदि नया आकार आवंटित आकार के आधे से कम है तो सूची सिकुड़ जाती है।आप उस स्लॉट 4 को अभी भी पूर्णांक को इंगित कर सकते हैं लेकिन महत्वपूर्ण बात सूची का आकार है जो अब 4 है। चलो एक और तत्व पॉप करते हैं। में
list_resize()
, आकार - 1 = 4 - 1 = 3 आवंटित स्लॉट के आधे से कम है इसलिए सूची 6 स्लॉट में सिकुड़ गई है और सूची का नया आकार अब 3 है।आप उस स्लॉट 3 और 4 को अभी भी कुछ पूर्णांकों की ओर इंगित कर सकते हैं लेकिन महत्वपूर्ण बात सूची का आकार है जो अब 3 है।
...
निकालें पायथन सूची ऑब्जेक्ट में किसी विशिष्ट तत्व को निकालने की एक विधि है
l.remove(5)
:।
aggregation
, नहीं composition
। काश रचना की भी एक सूची होती।
प्रलेखन के अनुसार ,
पायथन की सूचियाँ वास्तव में परिवर्तनशील-लंबाई की सरणियाँ हैं, लिस्प-शैली से जुड़ी सूचियाँ नहीं।
जैसा कि दूसरों ने ऊपर कहा है, सूचियों (जब सराहना बड़ी) को अंतरिक्ष की एक निश्चित राशि आवंटित करके कार्यान्वित किया जाता है, और, अगर उस स्थान को भरना चाहिए, तो बड़ी मात्रा में स्थान आवंटित करना और तत्वों की नकल करना।
यह समझने के लिए कि विधि O (1) परिशोधन के बिना सामान्यीकृत क्यों है, मान लें कि हमने एक = 2 ^ n तत्व डाला है, और हमें अब अपनी तालिका 2 ^ (n + 1) आकार से दोगुनी करनी होगी। इसका मतलब है कि हम वर्तमान में 2 ^ (n + 1) ऑपरेशन कर रहे हैं। अंतिम प्रतिलिपि, हमने 2 ^ एन ऑपरेशन किए। इससे पहले हमने 2 ^ (n-1) किया था ... सभी तरह से नीचे 8,4,2,1। अब, अगर हम इन्हें जोड़ते हैं, तो हमें 1 + 2 + 4 + 8 + ... + 2 ^ (n + 1) = 2 ^ (n + 2) - 1 <4 * 2 ^ n = O (2 ^) मिलता है n) = O (a) कुल सम्मिलन (यानी O (1) परिशोधन समय)। इसके अलावा, यह ध्यान दिया जाना चाहिए कि यदि तालिका हटाए जाने की अनुमति देती है तो तालिका को अलग कारक (जैसे 3x) पर सिकुड़ना पड़ता है
पायथन में एक सूची एक सरणी की तरह कुछ है, जहां आप कई मान संग्रहीत कर सकते हैं। सूची परिवर्तनशील है इसका मतलब है कि आप इसे बदल सकते हैं। अधिक महत्वपूर्ण बात जो आपको पता होनी चाहिए, जब हम एक सूची बनाते हैं, तो पायथन स्वचालित रूप से उस सूची चर के लिए एक reference_id बनाता है। यदि आप इसे बदलकर दूसरों को बदलते हैं तो मुख्य सूची बदल जाएगी। आइए एक उदाहरण के साथ प्रयास करें:
list_one = [1,2,3,4]
my_list = list_one
#my_list: [1,2,3,4]
my_list.append("new")
#my_list: [1,2,3,4,'new']
#list_one: [1,2,3,4,'new']
हम संलग्न हैं, my_list
लेकिन हमारी मुख्य सूची बदल गई है। इसका मतलब यह है कि सूची की नकल के रूप में असाइन नहीं की गई सूची इसके संदर्भ के रूप में असाइन की गई है।