පහත සඳහන් කරුණු සලකා බලන්න:
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
?
Answers:
ලැයිස්තුවක ප්රමාණය ලබා ගන්නේ කෙසේද?
ලැයිස්තුවක ප්රමාණය සොයා ගැනීමට, බිල්ඩින් ශ්රිතය භාවිතා කරන්න , 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()
. වස්තුවක දිග ආපසු ලබා දිය යුතුය, පූර්ණ සංඛ්යාවක්> = 0. එසේම,__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]
අත්යවශ්යයෙන්ම, එය OOP- හිතකාමී length
දේපලක් තිබීමේ අමතර වාසිය සමඟ ලැයිස්තු වස්තුවකට හරියටම සමාන වේ .
සෑම විටම මෙන්, ඔබේ සැතපුම් ගණන වෙනස් විය හැකිය.
length = property(len)
එක් පේළියේ එතීමේ කාර්යය මඟ හැර len
ඔබේ දේපල සමඟ ලියකියවිලි / ස්වයං විමර්ශනය තබා ගත හැකිය.
අමතරව len
ඔබ ද භාවිතා කළ හැකිය operator.length_hint
(Python 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
අගය) ඉක්මවන negative ණ දිග හෝ දිගට ඉඩ නොදේ . එබැවින් ක්රමය len
වෙනුවට ශ්රිතය භාවිතා කිරීම සැමවිටම ආරක්ෂිත වේ __len__
!
මීට පෙර ලබා දී ඇති උදාහරණ ලෙස ඔබේ ප්රශ්නයට පිළිතුරු සැපයීම:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
print items.__len__()
__foo__
: මෙය සම්මුතියක් පමණි, පයිතන් පද්ධතියට පරිශීලක නම් සමඟ නොගැලපෙන නම් භාවිතා කිරීමට මාර්ගයකි. 2 . _foo
: මෙය සම්මුතියක් පමණි, විචල්යය පුද්ගලික බව පෙන්වීමට ක්රමලේඛකයාට මාර්ගයකි (පයිතන් හි අර්ථය කුමක් වුවත්). 3 . __foo
: මෙය සැබෑ අරුතක් ඇත: පරිවර්තකයා මෙම නම _classname__foo
වෙනත් පන්තියක සමාන නමක් සමඟ නොගැලපෙන බව සහතික කිරීම සඳහා මෙම නම ආදේශ කරයි . පයිතන් ලෝකයේ වෙනත් කිසිම ආකාරයක අවධාරනයකට අර්ථයක් නැත. * මෙම සම්මුතීන් තුළ පන්තිය, විචල්යය, ගෝලීය යනාදිය අතර වෙනසක් නොමැත.
සම්පූර්ණත්වය සඳහා (මූලික වශයෙන් අධ්යාපනික), 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
වැඩි කිරීමට භාවිතා කරමි .
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
ආපසු ලබා දෙනු ලැබේ. සියලුම පයිතන් නිඛිල longs
පයිතන් 3 සිට ගබඩා කර ඇත.
මම මෙය සිදු කර ඇත්තේ කාර්යයන් භාවිතා කරමිනි:
#BLL
def count(lis): #defining a function which takes an iterator(here list) as argument
c=0 #assigning 0 value to a variable 'c'
for i in lis: #This for loop will run as many times as there are elements in the list/iterator
c+=1 #incrementing value of c. So every time loop runs: 1 gets added
#thus we find out how many times the loop runs:how many elements the loop has
return c #we return this value
#PL
items = []
items.append("apple")
items.append("orange")
items.append("banana")
n=count(items) #value c returned, is stored in n
print(n)
මෙය අපේක්ෂිත ප්රතිදානය මුද්රණය කරනු ඇත 3
. මෙය ප්රයෝජනවත් වේ යැයි මම බලාපොරොත්තු වෙමි.