ලැයිස්තුවක ඇති මූලද්‍රව්‍ය ගණන මා ලබා ගන්නේ කෙසේද?


1948

පහත සඳහන් කරුණු සලකා බලන්න:

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

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

ලැයිස්තුවේ ඇති මූලද්‍රව්‍ය ගණන මා ලබා ගන්නේ කෙසේද items?


24
ඔබ පැහැදිලිවම ලැයිස්තුවේ ඇති මූලද්‍රව්‍ය ගණන ඉල්ලයි. මතකයේ ඇති වස්තුවේ ප්‍රමාණය සොයමින් සෙවුම්කරුවෙකු මෙහි පැමිණෙන්නේ නම්, ඔවුන් සොයන සත්‍ය ප්‍රශ්නය සහ පිළිතුරු මෙයයි: පයිතන්හි ඇති වස්තුවක ප්‍රමාණය තීරණය කරන්නේ කෙසේද?
ආරොන් හෝල්

Answers:


2657

මෙම len()දෙදෙනාම බිල්ට් වර්ග හා පුස්තකාල වර්ග - කාර්යය Python විවිධ වර්ග කිහිපයක් සමග භාවිතා කළ හැක. උදාහරණයක් වශයෙන්:

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

නිල 2.x ප්‍රලේඛනය මෙහි ඇත: නිල 3.x ප්‍රලේඛනය මෙහි ඇත:len()
len()


241

ලැයිස්තුවක ප්‍රමාණය ලබා ගන්නේ කෙසේද?

ලැයිස්තුවක ප්‍රමාණය සොයා ගැනීමට, බිල්ඩින් ශ්‍රිතය භාවිතා කරන්න , 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වඩාත් කියවිය හැකි හා වඩා ක්‍රියාකාරී වන්නේ මන්දැයි මම පැහැදිලි කරමි .


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]

අත්‍යවශ්‍යයෙන්ම, එය OOP- හිතකාමී lengthදේපලක් තිබීමේ අමතර වාසිය සමඟ ලැයිස්තු වස්තුවකට හරියටම සමාන වේ .

සෑම විටම මෙන්, ඔබේ සැතපුම් ගණන වෙනස් විය හැකිය.


19
ඔබ දන්නා පරිදි, ඔබට කළ හැක්කේ length = property(len)එක් පේළියේ එතීමේ කාර්යය මඟ හැර lenඔබේ දේපල සමඟ ලියකියවිලි / ස්වයං විමර්ශනය තබා ගත හැකිය.
ටැඩ් මැක්ඩොනල්ඩ්-ජෙන්සන්

18

අමතරව 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__!


8

මීට පෙර ලබා දී ඇති උදාහරණ ලෙස ඔබේ ප්‍රශ්නයට පිළිතුරු සැපයීම:

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

print items.__len__()

15
පයිතන්හි, යටි ඉරි වලින් ආරම්භ වන නම් අර්ථාන්විතව පොදු නොවන ක්‍රම වන අතර ඒවා පරිශීලකයින් විසින් භාවිතා නොකළ යුතුය.
ආරොන් හෝල්

2
1 . __foo__: මෙය සම්මුතියක් පමණි, පයිතන් පද්ධතියට පරිශීලක නම් සමඟ නොගැලපෙන නම් භාවිතා කිරීමට මාර්ගයකි. 2 . _foo: මෙය සම්මුතියක් පමණි, විචල්‍යය පුද්ගලික බව පෙන්වීමට ක්‍රමලේඛකයාට මාර්ගයකි (පයිතන් හි අර්ථය කුමක් වුවත්). 3 . __foo: මෙය සැබෑ අරුතක් ඇත: පරිවර්තකයා මෙම නම _classname__fooවෙනත් පන්තියක සමාන නමක් සමඟ නොගැලපෙන බව සහතික කිරීම සඳහා මෙම නම ආදේශ කරයි . පයිතන් ලෝකයේ වෙනත් කිසිම ආකාරයක අවධාරනයකට අර්ථයක් නැත. * මෙම සම්මුතීන් තුළ පන්තිය, විචල්‍යය, ගෝලීය යනාදිය අතර වෙනසක් නොමැත.
ෂායි ඇලොන්

4
පරිශීලකයා ලෙස ඔබ කෙලින්ම විශේෂ ක්‍රම භාවිතා නොකළ යුත්තේ මන්දැයි මෙම ප්‍රශ්නෝත්තරය පැහැදිලි කරයි: stackoverflow.com/q/40272161/541136
ආරොන් හෝල්

A ආරොන්හෝල් නමුත් ලෙන් ක්‍රියාකාරිත්වය සඳහා එය බොහෝ දුරට සමාන ය. එය ඉතා විශාල විචල්‍යයන් සඳහා වේගවත් විය හැකිය. කෙසේ වෙතත්, මට ඔබේ අදහස වැටහී ඇති අතර අපි භාවිතා කළ යුත්තේ ලෙන් (ඕබ්) මිස ඕබ් නොවේ .__ ලෙන් __ ().
ෂයි ඇලොන්

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වැඩි කිරීමට භාවිතා කරමි .
Granny Aching

RanGrannyAching මම විකල්ප කොලන් (පරාසය පිරිවිතර) පැහැදිලිව සඳහන් කළෙමි. අධ්‍යාපන අරමුණු සඳහා මා එහි පරාසය පිරිවිතරයෙන් ඉවත් කළෙමි - එය ඇඟවුම් කර ඇති බව දැන ගැනීම ප්‍රයෝජනවත් වේ. ඔබ යෝජනා කරන පරිදි - මගේ කේතයට සමාන ලැයිස්තු වර්ගයක් [] අනුමාන කෙරේ. වර්ධක ක්‍රියාකරු බාහිර විචල්‍යයකට 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ආපසු ලබා දෙනු ලැබේ. සියලුම පයිතන් නිඛිල longsපයිතන් 3 සිට ගබඩා කර ඇත.


3
සී ක්‍රියාත්මක කිරීම ගැන දැන ගැනීම හෝ දැන ගැනීම වැදගත් වන්නේ ඇයි?
cs95

මෙම ප්‍රශ්නය CPython සඳහා විශේෂිත නොවන බැවින් මෙම පිළිතුර නොමඟ යවන සුළු විය හැකිය. PyPy, IronPython, ... එය වෙනස් ආකාරයකින් ක්‍රියාත්මක කළ හැකිය.
MSeifert

0

මම මෙය සිදු කර ඇත්තේ කාර්යයන් භාවිතා කරමිනි:

#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. මෙය ප්‍රයෝජනවත් වේ යැයි මම බලාපොරොත්තු වෙමි.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.