पायथन: क्या पायथन सूचियाँ लेन () के लिए एक गिनती रखती हैं या यह प्रत्येक कॉल के लिए गणना करती है?


79

यदि मैं बहुत लंबी सूची में लेन () को कॉल करता रहता हूं, तो क्या मैं समय बर्बाद कर रहा हूं, या क्या यह पृष्ठभूमि में एक इंट काउंट रखता है?


इसने मुझे हमेशा डरा दिया। विशेष रूप से जब मेरे प्रोफाइलर ने मुझे बताया कि मैंने एक कार्यक्रम के 2.2 सेकंड बिताए हैं जो एक मिनट इस समारोह को बुला रहा है।
— नाथन

जवाबों:


87

चिंता न करें: बेशक यह गिनती बचाता है और इस प्रकार len()सूचियों पर एक बहुत सस्ता ऑपरेशन है। उसी तरह से तार, शब्दकोश और सेट के लिए सच है!


मेरा मानना ​​है कि यह अंतिम आइटम + 1 या कुछ के सूचकांक की तरह एक गिनती रखता है, और उस मेमोरी स्थान से लेन () के मूल्य को कॉल करता है। क्या मैं सही हू?
— geekidharsh

37

और यह पता लगाने का एक और तरीका है कि यह कैसे किया जाता है Google कोड खोज पर इसे देखने के लिए GitHub पर स्रोत को देखें , यदि आप स्रोत को स्वयं डाउनलोड नहीं करना चाहते हैं।

static Py_ssize_t list_length(PyListObject *a)
{
    return a->ob_size;
}


13

अपना कार्यक्रम लिखें ताकि यह स्पष्टता के लिए अनुकूलित हो और आसानी से बनाए रखा जा सके । क्या आपका कार्यक्रम एक कॉल के साथ स्पष्ट है len(foo)? फिर वह करें।

क्या आपको समय लगने की चिंता है? लिया गया समय मापने के लिए timeitमानक पुस्तकालय में मॉड्यूल का उपयोग करें , और देखें कि क्या यह आपके कोड में महत्वपूर्ण है।

आप ज्यादातर लोगों की तरह, आपके अनुमानों में गलत होंगे कि आपके कार्यक्रम के कौन से हिस्से सबसे धीमे हैं। अनुमान लगाने के प्रलोभन से बचें, और इसके बजाय यह पता लगाने के लिए मापें।

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


1
मैं अपनी नौकरी में सिर्फ कुछ महीनों के लिए कोडर हूं और मैं दोनों प्रथाओं का समर्थन करता हूं। टाइमर सामान पारंपरिक ज्ञान ("चयन .. रैंडम बहुत महंगा है") के एक बड़े शरीर के खिलाफ दो-लाइनों की रक्षा प्रदान करता है, जो आपके रास्ते में आ जाएगा।
— जेस्विन जोस

5

प्रश्न का उत्तर दिया गया है ( lenहे (1)), लेकिन यहां बताया गया है कि आप अपने लिए कैसे जांच सकते हैं:

$ python -m timeit -s "l = range(10)" "len(l)"
10000000 loops, best of 3: 0.119 usec per loop
$ python -m timeit -s "l = range(1000000)" "len(l)"
10000000 loops, best of 3: 0.131 usec per loop

हाँ, वास्तव में धीमी नहीं है।


3

एक पायथन "सूची" वास्तव में एक रहने योग्य सरणी है, एक लिंक की गई सूची नहीं है, इसलिए यह कहीं न कहीं आकार को संग्रहीत करता है।


0

इसकी लंबाई कहीं स्टोर करनी होती है, इसलिए आप हर बार आइटम की संख्या नहीं गिन रहे हैं।


4
चेतावनी दी है, यह जरूरी हर भाषा में सच नहीं है। कुछ भाषाएँ वास्तव में लिंक की गई सूची का उपयोग करती हैं, और आकार के बारे में मेटा डेटा को रख सकती हैं या नहीं भी। एक आदर्श उदाहरण लिस्प है, जहाँ सूचियाँ स्वयं को बनाने के लिए अपेक्षाकृत आदिम 2 सेल संरचनाओं का उपयोग करती हैं, कोई मेटाडेटा नहीं। इन मामलों में एक लंबाई कॉल में O (n) समय लगता है।
— एश्टन के
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.