আমি কীভাবে একটি তালিকার উপাদানগুলির সংখ্যা পেতে পারি?


1935

নিম্নোক্ত বিবেচনা কর:

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

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

আমি কীভাবে তালিকার উপাদানগুলির সংখ্যা পেতে পারি items?


23
আপনি অবশ্যই তালিকার উপাদানগুলির সংখ্যা জিজ্ঞাসা করছেন। যদি কোনও অনুসন্ধানকারী এখানে স্মৃতিতে অবজেক্টের আকার অনুসন্ধান করতে আসে, তবে এটিই আসল প্রশ্ন এবং উত্তর তারা খুঁজছেন: পাইথনের কোনও বস্তুর আকার আমি কীভাবে নির্ধারণ করব?
হারুন হলের

উত্তর:


2638

len()ফাংশন পাইথন বিভিন্ন বিভিন্ন ধরনের ব্যবহার করা যেতে পারে - উভয় বিল্ট-ইন ধরনের এবং গ্রন্থাগার ধরনের। উদাহরণ স্বরূপ:

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

অফিসিয়াল 2.x ডকুমেন্টেশন এখানে: অফিসিয়াল 3.x ডকুমেন্টেশন এখানে:len()
len()


238

কিভাবে একটি তালিকা আকার পেতে?

একটি তালিকার আকার খুঁজে পেতে, অন্তর্নির্মিত ফাংশনটি ব্যবহার করুন len:

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

এবং এখন:

len(items)

রিটার্ন 3

ব্যাখ্যা

পাইথনের সমস্ত কিছুই তালিকাভুক্ত একটি বস্তু। সমস্ত বাস্তব বস্তুর সি বাস্তবায়নের ক্ষেত্রে একটি শিরোনাম রয়েছে।

বিশেষত পাইথনের "আকার" সমেত তালিকা এবং অন্যান্য অনুরূপ বিল্টিন অবজেক্টগুলির বিশেষত একটি বৈশিষ্ট্য বলা হয় ob_size , যেখানে বস্তুর উপাদানগুলির সংখ্যা ক্যাশে থাকে। সুতরাং একটি তালিকার মধ্যে অবজেক্টের সংখ্যা চেক করা খুব দ্রুত।

তবে যদি আপনি যাচ্ছেন যে তালিকার আকার শূন্য বা না, তা ব্যবহার করবেন না len- পরিবর্তে তালিকাটি বুলিয়ান প্রসঙ্গে রাখুন - এটি খালি হলে মিথ্যা হিসাবে গণ্য হবে, অন্যথায় সত্য

ডক্স থেকে

len(s)

কোনও বস্তুর দৈর্ঘ্য (আইটেমের সংখ্যা) প্রদান করুন। যুক্তিটি সিকোয়েন্স (যেমন একটি স্ট্রিং, বাইটস, টিপল, তালিকা বা রেঞ্জ) বা সংগ্রহ (যেমন অভিধান, সেট বা হিমায়িত সেট) হতে পারে।

len__len__ডেটা মডেল ডক্স সহ , এর সাথে প্রয়োগ করা হয়েছে :

object.__len__(self)

বিল্ট-ইন ফাংশনটি বাস্তবায়নের জন্য ডেকে আনা হয়েছে len()। অবজেক্টের দৈর্ঘ্য, একটি পূর্ণসংখ্যা = = ০ ফিরে আসা উচিত, এছাড়াও, এমন একটি বস্তু যা __nonzero__()[পাইথন 2 বা __bool__()পাইথন 3 এ] পদ্ধতিটি সংজ্ঞায়িত করে না এবং যার __len__()পদ্ধতিটি শূন্য ফিরে আসে তাকে বুলিয়ান প্রসঙ্গে মিথ্যা হিসাবে বিবেচনা করা হয়।

এবং আমরা দেখতে পাই যে __len__এটি তালিকার একটি পদ্ধতি:

items.__len__()

রিটার্ন 3

বিল্টিন প্রকারের 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আরও পাঠযোগ্য এবং আরও পারফরম্যান্ট।


74

যদিও এটি "বাক্সের বাইরে" কার্যকারিতা হিসাবে অনেক বেশি অর্থবোধ করার কারণে এটি কার্যকর নাও হতে পারে তবে 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
__foo__: এটি কেবল একটি সম্মেলন, পাইথন সিস্টেমের এমন নাম ব্যবহারের উপায় যা ব্যবহারকারীর নামের সাথে বিরোধী না। ২ _foo: এটি কেবল একটি সম্মেলন, প্রোগ্রামারকে এটি নির্দেশ করার উপায় যে ভেরিয়েবলটি ব্যক্তিগত (পাইথনের অর্থ যা কিছু)। ৩ __foo.: এর আসল অর্থ রয়েছে: দোভাষী এই নামটির পরিবর্তে এই নামটি _classname__fooঅন্য শ্রেণীর সাথে একই নামের সাথে ওভারল্যাপ করবে না তা নিশ্চিত করে ces * পাইথন বিশ্বে আর কোনও ধরণের আন্ডারস্কোরের অর্থ নেই। * এই সম্মেলনে শ্রেণি, পরিবর্তনশীল, গ্লোবাল ইত্যাদির মধ্যে কোনও পার্থক্য নেই।
শাই অ্যালন

4
এই প্রশ্নোত্তরটি ব্যাখ্যা করে যে আপনি কেন ব্যবহারকারী হিসাবে সরাসরি বিশেষ পদ্ধতি ব্যবহার করবেন না: stackoverflow.com/q/40272161/541136
অ্যারন হল

অ্যারোনহল @ লেন ফাংশনের জন্য এটি প্রায় একই। এটি খুব বড় ভেরিয়েবলগুলির জন্য দ্রুত হতে পারে। তবে আমি আপনার বক্তব্যটি পেয়েছি এবং আমাদের লেন (ওজেক্ট) ব্যবহার করা উচিত এবং আপত্তিজনক নয় __ লেন __ ()।
শাই অ্যালন

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[:] অন্তর্নিহিত এবং অতএব এটি optionচ্ছিকও))

নতুন প্রোগ্রামারদের জন্য এখানে পাঠটি হ'ল: আপনি তালিকায় আইটেমের সংখ্যা কোনও পর্যায়ে গণনা না করে পেতে পারবেন না। প্রশ্নটি হয়ে ওঠে: এগুলি গণনা করার ভাল সময় কখন? উদাহরণস্বরূপ, সকেটের জন্য কানেক্ট কানেক্ট সিস্টেম কলের মতো উচ্চ-সম্পাদন কোড (সি-তে লেখা) connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);, উপাদানগুলির দৈর্ঘ্য গণনা করে না (কলিং কোডটিকে সেই দায়িত্ব প্রদান করে)। লক্ষ্য করুন যে ঠিকানাটির দৈর্ঘ্যটি আগে দৈর্ঘ্য গণনা করার পদক্ষেপটি সংরক্ষণ করার জন্য পাশ করা হয়েছে? আরেকটি বিকল্প: গণনাগতভাবে, আপনি যে জিনিসটি পাস করবেন তার মধ্যে আইটেমের সংখ্যা যুক্ত করার সাথে সাথে তার সংখ্যার ট্র্যাক রাখা বুদ্ধিমান হতে পারে। মনে রাখবেন এটি মেমরিতে আরও স্থান নেয়। দেখুন Naftuli কে এর উত্তর

স্মৃতিতে আরও স্থান নেওয়ার সময় কর্মক্ষমতা উন্নত করতে দৈর্ঘ্যের উপর নজর রাখার উদাহরণ। নোট করুন যে আমি কখনই লেন () ফাংশনটি ব্যবহার করি না কারণ দৈর্ঘ্যটি ট্র্যাক করা হয়:

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ইনক্রিমেন্ট ব্যবহার করতাম ।
গ্র্যানি আঁচিং 19

@ গ্রানিআচিং আমি স্পষ্টভাবে colonচ্ছিক কলোন (রেঞ্জ স্পেসিফায়ার) উল্লেখ করেছি। আমি শিক্ষাগত উদ্দেশ্যে সেখানে রেঞ্জ স্পেসিফায়ার রেখেছি - এটি জড়িত তা জেনে রাখা উপকারী। আপনি যেমন আমার কোডের সমতুল্য পরামর্শ দিচ্ছেন তেমন একটি তালিকা ধরণের []ও অনুমান করা হয়। ইনক্রিমেন্ট অপারেটরটি একটি বিদ্যমান অস্থায়ী সাথে 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()একটি ফাংশন যা কোনও বস্তুর আকার দেয় returns যদি এটি কোনও বস্তুর আকার নির্ধারণ করতে না পারে তবে এটি -1 প্রদান করে। সেক্ষেত্রে এই কোড ব্লকটি কার্যকর করা হবে:

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

এবং ফলস্বরূপ একটি ব্যতিক্রম উত্থাপিত হয়। অন্যথায়, এই কোড ব্লকটি কার্যকর করা হবে:

return PyLong_FromSsize_t(res);

resযা একটি Cপূর্ণসংখ্যা, অজগরে রূপান্তরিত হয় longএবং ফিরে আসে। longsপাইথন 3 সাল থেকে সমস্ত পাইথন পূর্ণসংখ্যা সংরক্ষণ করা হয় ।


3
কেন সি বাস্তবায়ন সম্পর্কে জেনে বা জানা আছে?
সিএস 95

যেহেতু এই প্রশ্নটি সিপথনের সাথে সুনির্দিষ্ট নয় এই উত্তরটি বিভ্রান্তিকর হতে পারে। পাইপাই, আয়রন পাইথন, ... এটি আলাদাভাবে প্রয়োগ করতে পারে এবং করতে পারে।
এমসিফার্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.