मैं किसी सूची में तत्वों की संख्या कैसे प्राप्त करूं?


1937

निम्नलिखित को धयान मे रखते हुए:

items = []
items.append("apple")
items.append("orange")
items.append("banana")

# FAKE METHOD:
items.amount()  # Should return 3

मैं सूची में तत्वों की संख्या कैसे प्राप्त करूं items?


23
आप स्पष्ट रूप से सूची में तत्वों की संख्या के लिए पूछ रहे हैं। यदि कोई खोजकर्ता स्मृति में ऑब्जेक्ट के आकार की तलाश में यहां आता है, तो यह वास्तविक प्रश्न और उत्तर हैं जो वे खोज रहे हैं: मैं पायथन में किसी वस्तु के आकार का निर्धारण कैसे करूं?
एरोन हॉल

जवाबों:


2640

len()समारोह पायथन में विभिन्न प्रकार के साथ प्रयोग किया जा सकता है - दोनों में निर्मित प्रकार और पुस्तकालय प्रकार के। उदाहरण के लिए:

>>> len([1,2,3])
3

आधिकारिक 2.x प्रलेखन यहाँ है: आधिकारिक 3.x प्रलेखन यहाँ है:len()
len()


239

सूची का आकार कैसे प्राप्त करें?

सूची का आकार खोजने के लिए, बिल्टिन फ़ंक्शन का उपयोग करें len:

items = []
items.append("apple")
items.append("orange")
items.append("banana")

और अब:

len(items)

रिटर्न ३।

व्याख्या

पायथन में सब कुछ एक वस्तु है, जिसमें सूचियां भी शामिल हैं। सभी वस्तुओं के सी कार्यान्वयन में किसी प्रकार का हेडर है।

पायथन में "आकार" के साथ सूचियों और अन्य समान निर्मित वस्तुओं, विशेष रूप से, एक विशेषता कहा जाता है ob_size, जहां ऑब्जेक्ट में तत्वों की संख्या कैश की जाती है। इसलिए किसी सूची में वस्तुओं की संख्या की जाँच करना बहुत तेज़ है।

लेकिन अगर आप जाँच कर रहे हैं कि सूची का आकार शून्य है या नहीं, तो उपयोग न करें len- इसके बजाय, सूची को एक बूलियन संदर्भ में रखें - यह रिक्त के रूप में माना जाता है यदि रिक्त, सत्य अन्यथा

से डॉक्स

len(s)

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

len__len__डेटा मॉडल डॉक्स से लागू किया गया है :

object.__len__(self)

अंतर्निहित फ़ंक्शन को लागू करने के लिए कहा जाता है len()। वस्तु की लंबाई वापस आनी चाहिए, एक पूर्णांक> = 0. इसके अलावा, एक वस्तु जो __nonzero__()[2 पायथन में या __bool__()पायथन 3 में] को परिभाषित नहीं करती है, और जिसकी __len__()विधि शून्य मानती है, बूलियन संदर्भ में गलत माना जाता है।

और हम यह भी देख सकते हैं कि __len__सूचियों की एक विधि है:

items.__len__()

रिटर्न ३।

बिल्टइन प्रकार आप len(लंबाई) प्राप्त कर सकते हैं

और वास्तव में हम देखते हैं कि हम सभी प्रकारों के लिए यह जानकारी प्राप्त कर सकते हैं:

>>> all(hasattr(cls, '__len__') for cls in (str, bytes, tuple, list, 
                                            xrange, dict, set, frozenset))
True

lenखाली या गैर-रिक्त सूची के लिए परीक्षण करने के लिए उपयोग न करें

एक विशिष्ट लंबाई के लिए परीक्षण करने के लिए, बस समानता के लिए परीक्षण करें:

if len(items) == required_length:
    ...

लेकिन शून्य लंबाई सूची या व्युत्क्रम के परीक्षण के लिए एक विशेष मामला है। उस मामले में, समानता के लिए परीक्षण न करें।

इसके अलावा, ऐसा न करें:

if len(items): 
    ...

इसके बजाय, बस करो:

if items:     # Then we have some items, not empty!
    ...

या

if not items: # Then we have an empty list!
    ...

मैं समझाता हूं कि यहां क्यों लेकिन संक्षेप में, if itemsया if not itemsअधिक पठनीय और अधिक प्रदर्शन करने वाला दोनों है।


75

हालांकि यह इस तथ्य के कारण उपयोगी नहीं हो सकता है कि यह "बॉक्स से बाहर" कार्यक्षमता के रूप में बहुत अधिक समझ में आता है, एक lengthसंपत्ति के साथ एक वर्ग बनाने के लिए एक काफी सरल हैक होगा :

class slist(list):
    @property
    def length(self):
        return len(self)

आप इसे इस तरह से उपयोग कर सकते हैं:

>>> l = slist(range(10))
>>> l.length
10
>>> print l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

अनिवार्य रूप से, यह एक ओओपी-अनुकूल lengthसंपत्ति होने के अतिरिक्त लाभ के साथ, एक सूची वस्तु के समान है ।

हमेशा की तरह, आपके माईलेज़ भिन्न हो सकते हैं।


19
बस इतना है कि आप जानते हैं, आप बस कर सकते हैं length = property(len)और एक पंक्ति आवरण फ़ंक्शन को छोड़ सकते हैं और lenअपनी संपत्ति के साथ प्रलेखन / आत्मनिरीक्षण रख सकते हैं।
तदह मैकडॉनल्ड्स-जेनसेन

17

इसके अलावा lenआप भी उपयोग कर सकते हैं operator.length_hint(पाइथन 3.4+ की आवश्यकता है)। एक सामान्य के लिए listदोनों समान हैं, लेकिन length_hintएक सूची-पुनरावृत्त की लंबाई प्राप्त करना संभव बनाता है, जो कुछ परिस्थितियों में उपयोगी हो सकता है:

>>> from operator import length_hint
>>> l = ["apple", "orange", "banana"]
>>> len(l)
3
>>> length_hint(l)
3

>>> list_iterator = iter(l)
>>> len(list_iterator)
TypeError: object of type 'list_iterator' has no len()
>>> length_hint(list_iterator)
3

लेकिन length_hintपरिभाषा के अनुसार केवल एक "संकेत" है, इसलिए अधिकांश समय lenबेहतर है।

मैंने कई उत्तरों को एक्सेस करने का सुझाव दिया है __len__। बिल्ट-इन कक्षाओं जैसे काम करते समय यह सब ठीक है list, लेकिन यह कस्टम कक्षाओं के साथ समस्याओं का कारण बन सकता है, क्योंकि len(और length_hint) कुछ सुरक्षा जांचों को लागू करते हैं। उदाहरण के लिए, दोनों नकारात्मक लंबाई या लंबाई की अनुमति नहीं देते हैं जो एक निश्चित मूल्य ( sys.maxsizeमूल्य) से अधिक है। इसलिए यह विधि के lenबजाय फ़ंक्शन का उपयोग करने के लिए हमेशा सुरक्षित है __len__!


8

पहले दिए गए उदाहरणों के रूप में अपने प्रश्न का उत्तर देना:

items = []
items.append("apple")
items.append("orange")
items.append("banana")

print items.__len__()

15
पायथन में, अंडरस्कोर से शुरू होने वाले नाम शब्दार्थिक रूप से गैर-सार्वजनिक तरीके हैं और उपयोगकर्ताओं द्वारा उपयोग नहीं किए जाने चाहिए।
हारून हॉल

2
1 __foo__.: यह सिर्फ एक कन्वेंशन है, पायथन सिस्टम के लिए उन नामों का उपयोग करने का जो उपयोगकर्ता नामों के साथ संघर्ष नहीं करेंगे। 2 _foo.: यह सिर्फ एक कन्वेंशन है, प्रोग्रामर के लिए यह दर्शाने का एक तरीका है कि वैरिएबल निजी है (पाइथन में जो भी मतलब है)। 3. __foo- इसका वास्तविक अर्थ है: दुभाषिया इस नाम के साथ यह _classname__fooसुनिश्चित करने के तरीके की जगह लेता है कि यह नाम किसी अन्य वर्ग में समान नाम के साथ ओवरलैप नहीं होगा। * अंडरस्कोर के किसी अन्य रूप का अर्थ पायथन दुनिया में नहीं है। * इन सम्मेलनों में वर्ग, चर, वैश्विक आदि के बीच कोई अंतर नहीं है।
Shai Alon

4
यह क्यू एंड ए बताता है कि क्यों आप एक उपयोगकर्ता के रूप में सीधे विशेष विधियों का उपयोग नहीं करना चाहिए: stackoverflow.com/q/40272161/541136
हारून हॉल

@AaronHall लेकिन लेन फ़ंक्शन के लिए यह लगभग समान है। यह बहुत बड़े चर के लिए तेज़ हो सकता है। हालाँकि, मुझे आपकी बात मिल गई है और हमें लेन (obj) का उपयोग करना चाहिए न कि obj .__ len __ () का।
Shai Alon

7

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

def count(list):
    item_count = 0
    for item in list[:]:
        item_count += 1
    return item_count

count([1,2,3,4,5])

(में बृहदान्त्र list[:] अंतर्निहित है और इसलिए वैकल्पिक भी है।)

नए प्रोग्रामर के लिए यहां सबक यह है: आप किसी सूची में आइटम की संख्या को किसी बिंदु पर गिने बिना नहीं प्राप्त कर सकते हैं। सवाल बन जाता है: उन्हें गिनने का अच्छा समय कब है? उदाहरण के लिए, उच्च-प्रदर्शन कोड जैसे कनेक्ट सिस्टम कॉल सॉकेट्स के लिए (सी में लिखा गया है) connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);, तत्वों की लंबाई (कॉलिंग कोड को जिम्मेदारी देते हुए) की गणना नहीं करता है। ध्यान दें कि पहले लंबाई की गिनती के चरण को बचाने के लिए पते की लंबाई को पारित किया जाता है? एक अन्य विकल्प: कम्प्यूटेशनल रूप से, यह आपके द्वारा पास की जाने वाली वस्तु के भीतर जोड़ते समय वस्तुओं की संख्या पर नज़र रखने के लिए समझ में आता है। मन कि यह स्मृति में अधिक जगह लेता है। देखिए नफ़तुली के का जवाब

स्मृति में अधिक स्थान लेते हुए प्रदर्शन में सुधार करने के लिए लंबाई पर नज़र रखने का उदाहरण। ध्यान दें कि मैं कभी भी लेन () फ़ंक्शन का उपयोग नहीं करता क्योंकि लंबाई ट्रैक की जाती है:

class MyList(object):
    def __init__(self):
        self._data = []
        self.length = 0 # length tracker that takes up memory but makes length op O(1) time


        # the implicit iterator in a list class
    def __iter__(self):
        for elem in self._data:
            yield elem

    def add(self, elem):
        self._data.append(elem)
        self.length += 1

    def remove(self, elem):
        self._data.remove(elem)
        self.length -= 1

mylist = MyList()
mylist.add(1)
mylist.add(2)
mylist.add(3)
print(mylist.length) # 3
mylist.remove(3)
print(mylist.length) # 2

क्यों for item in list[:]:? क्यों नहीं for item in list:? इसके अलावा, मैं += 1वेतन वृद्धि का उपयोग करूंगा ।
दादी चाची

@GrannyAching मैंने स्पष्ट रूप से वैकल्पिक बृहदान्त्र (रेंज स्पेसियर) का उल्लेख किया है। मैंने शैक्षिक उद्देश्यों के लिए वहां रेंज स्पेसियर छोड़ दिया-यह जानना फायदेमंद है कि यह निहित है। एक सूची प्रकार [] के रूप में अच्छी तरह से अनुमान लगाया गया है, जैसा कि आप सुझाव देते हैं-मेरे कोड के समतुल्य। वेतन वृद्धि ऑपरेटर भी एक एक्सिसिटिंग वैरिएबल में 1 जोड़ने के बराबर है, फिर भी सभी मामलों में छोटा है। तो मैं सहमत हूँ कि इसका इस्तेमाल किया जाना चाहिए अगर यह आपके तर्क है। इस कोड को कहीं भी उत्पादन में नहीं डाला जाना चाहिए, वैसे भी (प्रोग्रामिंग सीखने के अलावा)।
जोनाथन कोमार

0

len()वास्तव में कैसे काम करता है के संदर्भ में , यह इसका सी कार्यान्वयन है :

static PyObject *
builtin_len(PyObject *module, PyObject *obj)
/*[clinic end generated code: output=fa7a270d314dfb6c input=bc55598da9e9c9b5]*/
{
    Py_ssize_t res;

    res = PyObject_Size(obj);
    if (res < 0) {
        assert(PyErr_Occurred());
        return NULL;
    }
    return PyLong_FromSsize_t(res);
}

Py_ssize_tअधिकतम लंबाई है कि वस्तु हो सकती है। PyObject_Size()एक ऐसा कार्य है जो किसी वस्तु का आकार देता है। यदि यह किसी वस्तु के आकार को निर्धारित नहीं कर सकता है, तो यह -1 देता है। उस स्थिति में, यह कोड ब्लॉक निष्पादित किया जाएगा:

if (res < 0) {
        assert(PyErr_Occurred());
        return NULL;
    }

और एक परिणाम के रूप में एक अपवाद उठाया जाता है। अन्यथा, यह कोड ब्लॉक निष्पादित किया जाएगा:

return PyLong_FromSsize_t(res);

resजो एक Cपूर्णांक है, एक अजगर में परिवर्तित हो जाता है longऔर वापस आ जाता है। सभी अजगर पूर्णांक longs3 पायथन के बाद से संग्रहीत हैं ।


3
C कार्यान्वयन मामले के बारे में जानना या जानना क्यों आवश्यक है?
cs95

चूंकि यह प्रश्न CPython के लिए विशिष्ट नहीं है, इसलिए यह उत्तर भ्रामक हो सकता है। PyPy, IronPython, ... इसे अलग तरीके से लागू और कर सकते हैं।
MSeifert
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.