Aşağıdakileri göz önünde bulundur:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
# FAKE METHOD:
items.amount() # Should return 3
Listedeki eleman sayısını nasıl alabilirim items
?
Aşağıdakileri göz önünde bulundur:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
# FAKE METHOD:
items.amount() # Should return 3
Listedeki eleman sayısını nasıl alabilirim items
?
Yanıtlar:
Bir listenin boyutu nasıl alınır?
Bir listenin boyutunu bulmak için yerleşik işlevini kullanın len
:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
Ve şimdi:
len(items)
3 döndürür.
Python'daki her şey, listeler dahil olmak üzere bir nesnedir. Tüm nesnelerin C uygulamasında bir tür başlığı vardır.
Özellikle Python'da "boyutu" olan listeler ve diğer benzer yerleşik nesneler ob_size
, nesnedeki öğelerin sayısının önbelleğe alındığı bir özniteliğe sahiptir . Dolayısıyla listedeki nesne sayısını kontrol etmek çok hızlıdır.
Ancak liste boyutunun sıfır olup olmadığını kontrol ediyorsanız, bunu kullanmayın len
- bunun yerine listeyi bir boole bağlamına yerleştirin - boşsa Yanlış olarak kabul edilir, aksi takdirde True olarak kullanılır .
len(s)
Bir nesnenin uzunluğunu (öğe sayısı) döndürün. Argüman bir dizi (dize, bayt, demet, liste veya aralık gibi) veya bir koleksiyon (sözlük, küme veya dondurulmuş küme gibi) olabilir.
len
ile uygulanan __len__
veri modeli dan, docs :
object.__len__(self)
Yerleşik işlevi uygulamak için çağrılır
len()
. Nesnenin uzunluğunu döndürmeli, tamsayı> = 0 olmalıdır. Ayrıca,__nonzero__()
[Python 2 veya__bool__()
Python 3'te] yöntemini tanımlamayan ve__len__()
yöntemi sıfır döndüren bir nesne Boole bağlamında yanlış kabul edilir.
Ve bunun __len__
bir liste yöntemi olduğunu da görebiliriz :
items.__len__()
3 döndürür.
len
(uzunluk)Aslında, bu bilgiyi açıklanan tüm türler için alabileceğimizi görüyoruz:
>>> all(hasattr(cls, '__len__') for cls in (str, bytes, tuple, list,
xrange, dict, set, frozenset))
True
len
Boş veya boş bir listeyi test etmek için kullanmayınBelirli bir uzunluğu test etmek için elbette eşitliği test edin:
if len(items) == required_length:
...
Ancak sıfır uzunluklu bir liste veya tersi için test etmek için özel bir durum vardır. Bu durumda, eşitliği test etmeyin.
Ayrıca, şunları yapmayın:
if len(items):
...
Bunun yerine, şunları yapın:
if items: # Then we have some items, not empty!
...
veya
if not items: # Then we have an empty list!
...
Ben niye burada açıklamak ancak Kısacası, if items
ya if not items
ikisi daha okunabilir ve daha performanslısı.
Bu, "kutunun dışında" işlevselliği olarak çok daha mantıklı olması nedeniyle yararlı olmasa da, oldukça basit bir kesmek, bir length
özellikli bir sınıf oluşturmak olacaktır :
class slist(list):
@property
def length(self):
return len(self)
Şöyle kullanabilirsiniz:
>>> l = slist(range(10))
>>> l.length
10
>>> print l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Temel olarak, OOP dostu bir length
özelliğe sahip olmanın ek avantajı ile bir liste nesnesiyle tamamen aynıdır .
Her zaman olduğu gibi, kilometreniz değişebilir.
length = property(len)
tek satırlık sarma işlevini atlayıp atlayabilir ve len
mülkünüzle ilgili belgeleri / içgörüleri koruyabilirsiniz .
Ayrıca len
kullanabilirsiniz operator.length_hint
(Python 3.4+ gerektirir). Normal için list
her ikisi de eşdeğerdir, ancak length_hint
belirli durumlarda yararlı olabilecek bir liste yineleyicinin uzunluğunu almayı mümkün kılar:
>>> 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
Ancak length_hint
tanım gereği sadece bir "ipucu" olduğundan, çoğu zaman len
daha iyidir.
Erişmeyi öneren birkaç yanıt gördüm __len__
. Bu gibi yerleşik sınıflarla uğraşırken list
sorun yoktur, ancak özel sınıflarla ilgili sorunlara yol açabilir, çünkü len
(ve length_hint
) bazı güvenlik kontrolleri uygular. Örneğin, her ikisi de belirli bir değeri ( sys.maxsize
değeri) aşan negatif uzunluklara veya uzunluklara izin vermez . Bu nedenle yöntem len
yerine işlevi kullanmak her zaman daha güvenlidir __len__
!
Sorunuzu daha önce verilen örnekler olarak cevaplamak:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
print items.__len__()
__foo__
.: Bu sadece bir kuraldır, Python sisteminin kullanıcı adlarıyla çakışmayan adları kullanmasının bir yoludur. 2 _foo
.: Bu sadece bir kural, programcının değişkenin özel olduğunu (Python'da ne anlama gelirse) belirtmesinin bir yoludur. 3 __foo
.: bunun gerçek bir anlamı vardır: tercüman _classname__foo
, ismin başka bir sınıfta benzer bir isimle örtüşmemesini sağlamak için bu ismi değiştirir. * Python dünyasında başka hiçbir alt çizginin anlamı yoktur. * Bu sözleşmelerde sınıf, değişken, küresel vb. Arasında fark yoktur.
Ve bütünlük için (öncelikle eğitim amaçlı), len()
işlevi kullanmadan mümkündür . Ben iyi bir seçenek olarak kabul edemeyeceği DO NOT PROGRAMI GİBİ BU İÇİNDE PYTHON ama algoritmaları öğrenmek için bir amaca hizmet eder.
def count(list):
item_count = 0
for item in list[:]:
item_count += 1
return item_count
count([1,2,3,4,5])
(İki nokta üst üste işareti list[:]
örtüktür ve bu nedenle isteğe bağlıdır.)
Burada yeni programcılar için ders şöyledir: Bir listedeki öğelerin sayısını bir noktada saymadan alamazsınız. Soru şu: Onları saymak için iyi bir zaman ne zaman? Örneğin, bağlantı sistemi (C ile yazılmış) için bağlantı sistemi çağrısı gibi yüksek performanslı kod connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
, öğelerin uzunluğunu hesaplamaz (bu kodu arama koduna verir). Önce uzunluğu sayma adımını kaydetmek için adresin uzunluğunun geçtiğine dikkat edin? Başka bir seçenek: hesaplama olarak, ilettiğiniz nesne içine eklerken öğe sayısını takip etmek mantıklı olabilir. Bunun bellekte daha fazla yer kapladığını unutmayın. Bkz Naftuli Kay cevabı .
Bellekte daha fazla yer kaplarken performansı artırmak için uzunluğu takip etme örneği. Uzunluk izlendiğinden asla len () işlevini kullanmamam gerektiğini unutmayın:
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[:]:
? Neden olmasın for item in list:
? Ayrıca, += 1
artırmak için kullanırdım .
Gerçekte nasıl len()
çalıştığı açısından , bu C uygulamasıdır :
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
nesnenin sahip olabileceği maksimum uzunluktur. PyObject_Size()
bir nesnenin boyutunu döndüren bir işlevdir. Bir nesnenin boyutunu belirleyemezse -1 döndürür. Bu durumda, bu kod bloğu yürütülür:
if (res < 0) {
assert(PyErr_Occurred());
return NULL;
}
Ve sonuç olarak bir istisna ortaya çıkıyor. Aksi takdirde, bu kod bloğu yürütülür:
return PyLong_FromSsize_t(res);
res
C
tamsayı olan bir python'a dönüştürülür long
ve döndürülür. Tüm python tam sayıları longs
Python 3'ten beri saklanır .