Folgendes berücksichtigen:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
# FAKE METHOD:
items.amount() # Should return 3
Wie erhalte ich die Anzahl der Elemente in der Liste items?
Folgendes berücksichtigen:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
# FAKE METHOD:
items.amount() # Should return 3
Wie erhalte ich die Anzahl der Elemente in der Liste items?
Antworten:
Wie erhalte ich die Größe einer Liste?
Verwenden Sie die integrierte Funktion, um die Größe einer Liste zu ermitteln len:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
Und nun:
len(items)
gibt 3 zurück.
Alles in Python ist ein Objekt, einschließlich Listen. Alle Objekte haben in der C-Implementierung eine Art Header.
Insbesondere Listen und andere ähnliche integrierte Objekte mit einer "Größe" in Python haben ein Attribut namens ob_size, bei dem die Anzahl der Elemente im Objekt zwischengespeichert wird. Das Überprüfen der Anzahl der Objekte in einer Liste ist daher sehr schnell.
Wenn Sie jedoch überprüfen, ob die Listengröße Null ist oder nicht, verwenden Sie sie nicht len. Setzen Sie die Liste stattdessen in einen booleschen Kontext. Sie wird als falsch behandelt, wenn sie leer ist, andernfalls als wahr .
len(s)
Gibt die Länge (die Anzahl der Elemente) eines Objekts zurück. Das Argument kann eine Sequenz (z. B. eine Zeichenfolge, Bytes, ein Tupel, eine Liste oder ein Bereich) oder eine Sammlung (z. B. ein Wörterbuch, eine Menge oder eine eingefrorene Menge) sein.
lenimplementiert mit __len__, aus dem Datenmodell docs :
object.__len__(self)
Wird aufgerufen, um die integrierte Funktion zu implementieren
len(). Sollte die Länge des Objekts zurückgeben, eine Ganzzahl> = 0. Auch ein Objekt, das keine__nonzero__()[in Python 2 oder__bool__()in Python 3] -Methode definiert und dessen__len__()Methode Null zurückgibt, wird in einem booleschen Kontext als falsch betrachtet.
Und wir können auch sehen, dass dies __len__eine Methode von Listen ist:
items.__len__()
gibt 3 zurück.
lenLänge Sie erhalten könnenUnd tatsächlich sehen wir, dass wir diese Informationen für alle beschriebenen Typen erhalten können:
>>> all(hasattr(cls, '__len__') for cls in (str, bytes, tuple, list,
xrange, dict, set, frozenset))
True
lenzum Testen auf eine leere oder nicht leere Liste verwendenUm auf eine bestimmte Länge zu testen, testen Sie natürlich einfach die Gleichheit:
if len(items) == required_length:
...
Es gibt jedoch einen Sonderfall für das Testen auf eine Liste mit der Länge Null oder die Umkehrung. In diesem Fall nicht auf Gleichheit prüfen.
Tun Sie auch nicht:
if len(items):
...
Tun Sie stattdessen einfach:
if items: # Then we have some items, not empty!
...
oder
if not items: # Then we have an empty list!
...
Ich erkläre warum hier aber kurz if itemsoder if not itemsist sowohl lesbarer als auch performanter.
Dies ist möglicherweise nicht sinnvoll, da es als "out of the box" -Funktionalität viel sinnvoller wäre. Ein ziemlich einfacher Hack wäre jedoch, eine Klasse mit einer lengthEigenschaft zu erstellen :
class slist(list):
@property
def length(self):
return len(self)
Sie können es so verwenden:
>>> l = slist(range(10))
>>> l.length
10
>>> print l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Im Wesentlichen ist es genau identisch mit einem Listenobjekt, mit dem zusätzlichen Vorteil einer OOP-freundlichen lengthEigenschaft.
Wie immer kann Ihr Kilometerstand variieren.
length = property(len)die einzeilige Wrapper-Funktion ausführen und überspringen und die Dokumentation / Selbstbeobachtung lenIhrer Immobilie beibehalten .
Außerdem können lenSie auch verwenden operator.length_hint(erfordert Python 3.4+). Für einen Normalen sind listbeide gleichwertig, aber length_hintes ist möglich, die Länge eines Listeniterators zu ermitteln, was unter bestimmten Umständen nützlich sein kann:
>>> 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
Ist length_hintaber per Definition nur ein "Hinweis", so ist die meiste Zeit lenbesser.
Ich habe mehrere Antworten gesehen, die auf einen Zugriff hinweisen __len__. Dies ist in Ordnung, wenn es sich um integrierte Klassen wie handelt list, kann jedoch zu Problemen mit benutzerdefinierten Klassen führen, da len(und length_hint) einige Sicherheitsüberprüfungen implementiert werden. Beispielsweise erlauben beide keine negativen Längen oder Längen, die einen bestimmten Wert (den sys.maxsizeWert) überschreiten . Es ist also immer sicherer, die lenFunktion anstelle der __len__Methode zu verwenden!
Beantworten Sie Ihre Frage anhand der zuvor angegebenen Beispiele:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
print items.__len__()
__foo__: Dies ist nur eine Konvention, eine Möglichkeit für das Python-System, Namen zu verwenden, die nicht mit Benutzernamen in Konflikt stehen. 2 . _foo: Dies ist nur eine Konvention, mit der der Programmierer angeben kann, dass die Variable privat ist (was auch immer dies in Python bedeutet). 3 . __foo: Dies hat eine echte Bedeutung: Der Interpreter ersetzt diesen Namen durch _classname__foo, um sicherzustellen, dass sich der Name nicht mit einem ähnlichen Namen in einer anderen Klasse überschneidet. * Keine andere Form von Unterstrichen hat in der Python-Welt eine Bedeutung. * In diesen Konventionen gibt es keinen Unterschied zwischen Klasse, Variable, Global usw.
Und der Vollständigkeit halber (hauptsächlich pädagogisch) ist es möglich, ohne die len()Funktion zu verwenden. Ich würde dies nicht als gute Option dulden. PROGRAMMIEREN SIE NICHT WIE DIESES IN PYTHON , aber es dient einem Zweck zum Lernen von Algorithmen.
def count(list):
item_count = 0
for item in list[:]:
item_count += 1
return item_count
count([1,2,3,4,5])
(Der Doppelpunkt in list[:]ist implizit und daher auch optional.)
Die Lektion für neue Programmierer lautet: Sie können die Anzahl der Elemente in einer Liste nicht ermitteln, ohne sie irgendwann zu zählen. Die Frage lautet: Wann ist ein guter Zeitpunkt, um sie zu zählen? Beispielsweise connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);berechnet Hochleistungscode wie der Verbindungssystemaufruf für Sockets (in C geschrieben) nicht die Länge von Elementen (wobei diese Verantwortung dem aufrufenden Code übertragen wird). Beachten Sie, dass die Länge der Adresse weitergegeben wird, um den Schritt des Zählens der Länge zuerst zu speichern. Eine weitere Option: Rechnerisch kann es sinnvoll sein, die Anzahl der Elemente zu verfolgen, wenn Sie sie in das übergebene Objekt einfügen. Beachten Sie, dass dies mehr Speicherplatz beansprucht. Siehe Naftuli Kays Antwort .
Beispiel für das Verfolgen der Länge, um die Leistung zu verbessern und gleichzeitig mehr Speicherplatz zu beanspruchen. Beachten Sie, dass ich die Funktion len () nie verwende, da die Länge verfolgt wird:
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[:]:? Warum nicht for item in list:? Außerdem würde ich verwenden, um += 1zu erhöhen.
In Bezug auf die len()tatsächliche Funktionsweise ist dies die C-Implementierung :
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_tist die maximale Länge, die das Objekt haben kann. PyObject_Size()ist eine Funktion, die die Größe eines Objekts zurückgibt. Wenn die Größe eines Objekts nicht bestimmt werden kann, wird -1 zurückgegeben. In diesem Fall wird dieser Codeblock ausgeführt:
if (res < 0) {
assert(PyErr_Occurred());
return NULL;
}
Infolgedessen wird eine Ausnahme ausgelöst. Andernfalls wird dieser Codeblock ausgeführt:
return PyLong_FromSsize_t(res);
resDies ist eine CGanzzahl, wird in eine Python konvertiert longund zurückgegeben. Alle Python-Ganzzahlen werden wie longsseit Python 3 gespeichert .