पायथन लिस्ट बनाम ऐरे - कब इस्तेमाल करना है?


374

यदि आप 1d सरणी बना रहे हैं, तो आप इसे एक सूची के रूप में लागू कर सकते हैं, या फिर मानक लाइब्रेरी में 'सरणी' मॉड्यूल का उपयोग कर सकते हैं। मैंने हमेशा 1d सरणियों के लिए सूचियों का उपयोग किया है।

वह कारण या परिस्थिति क्या है जहाँ मैं इसके बजाय सरणी मॉड्यूल का उपयोग करना चाहूंगा?

क्या यह प्रदर्शन और स्मृति अनुकूलन के लिए है, या मैं कुछ स्पष्ट याद कर रहा हूं?

जवाबों:


438

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

array.arrayप्रकार, दूसरे हाथ पर, बस सी सरणियों पर एक पतली आवरण है। यह केवल सजातीय डेटा, एक ही प्रकार के सभी को पकड़ सकता है, और इसलिए यह केवल sizeof(one object) * lengthमेमोरी के बाइट्स का उपयोग करता है । अधिकतर, आपको इसका उपयोग तब करना चाहिए जब आपको किसी एक्सटेंशन या सिस्टम कॉल (उदाहरण के लिए, ioctlया fctnl) के लिए C सरणी को उजागर करने की आवश्यकता हो ।

array.arrayपायथन 2.x ( ) में एक उत्परिवर्तनीय स्ट्रिंग का प्रतिनिधित्व करने का एक उचित तरीका भी है array('B', bytes)। हालाँकि, पायथन 2.6+ और 3.x के रूप में एक म्यूट बाइट स्ट्रिंग प्रदान करता हैbytearray

हालाँकि, यदि आप संख्यात्मक डेटा के समरूप सरणी पर गणित करना चाहते हैं , तो आप NumPy का उपयोग करके बहुत बेहतर हैं, जो जटिल बहु-आयामी सरणियों पर स्वचालित रूप से संचालन को वेक्टर कर सकते हैं।

एक लंबी कहानी को छोटा करने के लिए : array.arrayजब आपको गणित करने के अलावा अन्य कारणों से एक समरूप सी सरणी डेटा की आवश्यकता होती है, तब उपयोगी होता है ।


9
क्या numpy.ndarray में array.array के समान मेमोरी फ़ुटप्रिंट है?
गॉर्डन बीन

6
@ गोर्डन, यह एक बड़े, सन्निहित सरणी के मामले में बहुत समान होना चाहिए: उन्हें दोनों को sizeof(element)× (तत्वों की संख्या) बाइट्स की आवश्यकता होगी , साथ ही ओवरहेड के लिए एक छोटा फिक्स्ड हेडर। हालांकि, ndarray के पास असंगत और विरल सरणियों से निपटने के लिए कुछ उन्नत विकल्प हैं, और मुझे लगता है कि बड़े सरणियों के लिए मेमोरी आवंटित करने के लिए कुछ प्लगेबल रणनीतियाँ हैं ... इनमें से कुछ उन्नत सुविधाएँ इसे उपयोगकर्ता को कम मेमोरी बना देंगी , जबकि अन्य अधिक उपयोग करके प्रदर्शन में सुधार करेंगे। याद।
डैन लेन्स्की

यह भी उपयोगी है जब स्मृति एक समस्या है जैसे कि माइक्रोप्रिथन के साथ माइक्रो कंट्रोलर प्रोग्रामिंग करते समय
janscas

कोई निरंतर समय में सरणी के i'th तत्व को देख सकता है, जबकि लिंक की गई सूची में, यह सबसे खराब स्थिति में आदेश 'n' लेता है। एक अजगर सूची में i'th तत्व का खोज समय क्या है?
निथिश इनपरस्पेशल ऑफहापीनेस

7
@NithishInpursuitOfhappiness, पायथन सूची एक लिंक की गई सूची नहीं है। यह एक सरणी के रूप में आंतरिक रूप से दर्शाया गया है और इसमें जावा के एरियर लिस्ट के रूप में एक ही समय की जटिलता विशेषताएं हैं। इस प्रकार, पायथन सूची के i'th तत्व को प्राप्त करना और सेट करना निरंतर समय लेता है । एक तत्व को पायथन सूची में शामिल करने से लगातार स्थिर समय लगता है क्योंकि अंतरिक्ष से बाहर निकलते समय सरणी का आकार दोगुना हो जाता है। एक तत्व को पायथन सूची के बीच से हटाने या हटाने में O (n) समय लगता है क्योंकि तत्वों को स्थानांतरित करने की आवश्यकता होती है। संदर्भ के लिए, देखें: wiki.python.org/moin/TimeComplexity
geofflee

66

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


3
संभव है, इसका उपयोग वास्तव में कभी नहीं किया गया, लेकिन कुछ माइक्रो बेंचमार्क चलाना दिलचस्प होगा।
एंड्रे

13
वास्तव में, मैंने एक त्वरित परीक्षण किया - मैंने 100M प्रविष्टियों के साथ एक सूची को समन किया और उसी सारणी के साथ एक ही परीक्षण किया और सूची वास्तव में लगभग 10% तेज थी।
Moe

38
सूचियाँ तेज़ होती हैं, क्योंकि सरणी "रॉ" डेटा के संचालन को सरणी से पढ़ते या लिखते समय अजगर वस्तुओं को लगातार बनाने और नष्ट करने की आवश्यकता होती है।
tzot

7
@Moe, जैसा कि मैंने ऊपर मेरा उत्तर में बताया, पायथन के अंतर्निहित arrayहै गणित कर रही है के लिए नहीं । यदि आप ndarray10 ^ 8 नंबरों की संख्या के लिए NumPy की कोशिश करते हैं , तो यह पूरी तरह से listदूर हो जाएगा। @tzot के पास सही विचार है कि क्यों अंतर्निहित arrayगणित के लिए धीमा है।
Dan Lenski

2
मैंने अभी इसका परीक्षण किया, मेरी मशीन पर सुन्नता 86.6x तेज है।
मार्क

53

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

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

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

TL; DR मैं केवल एक सरणी का उपयोग करूँगा यदि आपको एक असाधारण अनुकूलन की आवश्यकता थी या आपको C कोड के साथ इंटरफ़ेस करने की आवश्यकता थी (और pyrex का उपयोग नहीं कर सकते )।


1
ठोस उदाहरण और उल्लेख गति लाभ के लिए +1। शीर्ष उत्तर ने मुझे आश्चर्यचकित कर दिया, "क्या कोई समय-स्मृति व्यापार है?" और "क्या इसके लिए कोई उपयोग है जो बहुत गूढ़ कम स्मृति वाला मामला नहीं है?"
लीव्ज

@leewz बिल्कुल, यह जवाब के रूप में माना जाना चाहिए।
गौरी शंकर बडोला

21

यह एक व्यापार बंद है!

प्रत्येक के नियम:

सूची

  • लचीला
  • विषम हो सकता है

सरणी (उदा: सुन्न सरणी)

  • समान मूल्यों की सरणी
  • सजातीय
  • कॉम्पैक्ट (आकार में)
  • कुशल (कार्यक्षमता और गति)
  • सुविधाजनक

2
सवाल अजगर में सरणी मॉड्यूल के लिए है; नहीं सुन्न arrays। आकार दक्षता को छोड़कर उनके पास बहुत सारे पेशेवरों की आवश्यकता नहीं है। वे तेज नहीं हैं।
NONONONONO

14

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


8

बाइनरी I / O के लिए मानक पुस्तकालय सरणियाँ उपयोगी हैं, जैसे कि एक तरंग फ़ाइल को लिखने के लिए, एक स्ट्रिंग को ints की सूची का अनुवाद करना। उस ने कहा, जैसा कि कई लोग पहले ही नोट कर चुके हैं, यदि आप कोई वास्तविक काम करने जा रहे हैं तो आपको NumPy का उपयोग करने पर विचार करना चाहिए।


6

यदि आप सरणियों का उपयोग करने जा रहे हैं, तो सुन्न या डरावने पैकेजों पर विचार करें, जो आपको बहुत अधिक लचीलेपन के साथ सरणियाँ देते हैं।


5

सरणी का उपयोग केवल विशिष्ट प्रकारों के लिए किया जा सकता है, जबकि सूचियों का उपयोग किसी भी वस्तु के लिए किया जा सकता है।

Arrays में केवल एक प्रकार का डेटा हो सकता है, जबकि एक सूची में विभिन्न ऑब्जेक्ट प्रकारों की प्रविष्टियाँ हो सकती हैं।

कुछ संख्यात्मक अभिकलन के लिए ऐरे भी अधिक कुशल हैं।


4
अंतर्निहित पाइथन सरणियां प्रदर्शन-वार कुशल नहीं हैं, केवल मेमोरी-वार हैं।
tzot

ऐसे उदाहरण हैं जहां प्रसंस्करण के संदर्भ में सरणियाँ अधिक कुशल हैं। नीचे मेरी पोस्ट देखें: stackoverflow.com/questions/176011/…
जेसन बेकर

0

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


0

यह उत्तर सूची और सरणी का उपयोग करने के बारे में लगभग सभी प्रश्नों का सारांश देगा:

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

  2. सूची अजगर के सिंटैक्स का हिस्सा है, इसलिए इसे घोषित करने की आवश्यकता नहीं है, जबकि आपको इसका उपयोग करने से पहले सरणी घोषित करना होगा।

  3. आप एक सूची (विषम) में विभिन्न डेटा-प्रकारों के मूल्यों को स्टोर कर सकते हैं, जबकि एरे में आप केवल एक ही डेटा-टाइप (सजातीय) के मूल्यों को स्टोर कर सकते हैं।

  4. कार्यात्मकताओं और तेजी से समृद्ध होने के कारण, यह व्यापक रूप से अंकगणितीय संचालन के लिए और डेटा की एक बड़ी मात्रा को संग्रहीत करने के लिए उपयोग किया जाता है - सूची की तुलना में।

  5. सूचियों की तुलना में Arrays कम मेमोरी लेती है।

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