নিম্নোক্ত বিবেচনা কর:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
# FAKE METHOD:
items.amount() # Should return 3
আমি কীভাবে তালিকার উপাদানগুলির সংখ্যা পেতে পারি items
?
নিম্নোক্ত বিবেচনা কর:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
# FAKE METHOD:
items.amount() # Should return 3
আমি কীভাবে তালিকার উপাদানগুলির সংখ্যা পেতে পারি items
?
উত্তর:
কিভাবে একটি তালিকা আকার পেতে?
একটি তালিকার আকার খুঁজে পেতে, অন্তর্নির্মিত ফাংশনটি ব্যবহার করুন 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
আরও পাঠযোগ্য এবং আরও পারফরম্যান্ট।
যদিও এটি "বাক্সের বাইরে" কার্যকারিতা হিসাবে অনেক বেশি অর্থবোধ করার কারণে এটি কার্যকর নাও হতে পারে তবে 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
সম্পত্তি থাকার অতিরিক্ত বেনিফিট সহ কোনও তালিকার অবজেক্টের সাথে হুবহু মিল ।
সর্বদা হিসাবে, আপনার মাইলেজ পরিবর্তিত হতে পারে।
length = property(len)
এক লাইনের মোড়ক ফাংশনটি করতে এবং এড়িয়ে যেতে পারেন এবং len
আপনার সম্পত্তির সাথে ডকুমেন্টেশন / ইনট্রোস্পেকশন রাখতে পারেন ।
এছাড়াও 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__
!
আপনার প্রশ্নের উত্তর আগে দেওয়া উদাহরণ হিসাবে দেওয়া:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
print items.__len__()
__foo__
: এটি কেবল একটি সম্মেলন, পাইথন সিস্টেমের এমন নাম ব্যবহারের উপায় যা ব্যবহারকারীর নামের সাথে বিরোধী না। ২ _foo
: এটি কেবল একটি সম্মেলন, প্রোগ্রামারকে এটি নির্দেশ করার উপায় যে ভেরিয়েবলটি ব্যক্তিগত (পাইথনের অর্থ যা কিছু)। ৩ __foo
.: এর আসল অর্থ রয়েছে: দোভাষী এই নামটির পরিবর্তে এই নামটি _classname__foo
অন্য শ্রেণীর সাথে একই নামের সাথে ওভারল্যাপ করবে না তা নিশ্চিত করে ces * পাইথন বিশ্বে আর কোনও ধরণের আন্ডারস্কোরের অর্থ নেই। * এই সম্মেলনে শ্রেণি, পরিবর্তনশীল, গ্লোবাল ইত্যাদির মধ্যে কোনও পার্থক্য নেই।
এবং সম্পূর্ণতার জন্য (প্রাথমিকভাবে শিক্ষামূলক), 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
ইনক্রিমেন্ট ব্যবহার করতাম ।
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 সাল থেকে সমস্ত পাইথন পূর্ণসংখ্যা সংরক্ষণ করা হয় ।