Antworten:
if not a:
print("List is empty")
Die implizite Booleschheit des Leeren zu verwenden, list
ist ziemlich pythonisch.
if a == []
zwingt einen bestimmten Typ ( () == []
ist False
). Hier scheint allgemeiner Konsens zu bestehen, dass die Typisierung von Enten gewinnt (in der Tat, dies __nonzero__
ist die Schnittstelle zum Testen der Leere docs.python.org/reference/datamodel.html#object.__nonzero__ )
Die pythonische Methode dazu stammt aus dem PEP 8- Styleguide (wobei Ja „empfohlen“ und Nein „nicht empfohlen“ bedeutet):
Verwenden Sie für Sequenzen (Zeichenfolgen, Listen, Tupel) die Tatsache, dass leere Sequenzen falsch sind.
Yes: if not seq: if seq: No: if len(seq): if not len(seq):
seq
es sich um ein listähnliches Objekt handelt.
Ich bevorzuge es ausdrücklich:
if len(li) == 0:
print('the list is empty')
Auf diese Weise ist zu 100% klar, dass li
es sich um eine Sequenz (Liste) handelt, und wir möchten ihre Größe testen. Mein Problem dabei if not li: ...
ist, dass es den falschen Eindruck vermittelt, dass li
es sich um eine boolesche Variable handelt.
li
ein Idiot ist, und es ist ihm egal. Wenn es wichtig ist, sollten Sie einen Kommentar hinzufügen, nicht mehr Code.
None
oder wollen 0
eine Ausnahme auslösen anstatt zu bestehen). Also, wenn Sie es ohne Grund tun, das ist irreführend-und es bedeutet auch , dass , wenn Ihr Code tut Notwendigkeit , den Unterschied zu machen, die Unterscheidung unsichtbar ist , weil Sie „ rufe Wolf“ auf dem ganzen Rest der Quelle haben.
if bool(len(li) == 0) is True:
?
Dies ist der erste Google-Treffer für "Python Test Empty Array" und ähnliche Abfragen, und andere Leute scheinen die Frage über reine Listen hinaus zu verallgemeinern. Daher dachte ich, ich würde eine Einschränkung für eine andere Art von Sequenz hinzufügen, die viele Leute haben verwenden könnte.
Sie müssen mit NumPy-Arrays vorsichtig sein, da andere Methoden, die für list
s oder andere Standardcontainer gut funktionieren , für NumPy-Arrays fehlschlagen. Ich erkläre unten, warum, aber kurz gesagt, die bevorzugte Methode ist die Verwendung size
.
Die "pythonische" Methode schlägt bei NumPy-Arrays fehl, da NumPy versucht, das Array in ein Array von bool
s umzuwandeln , und if x
versucht, alle diese bool
s gleichzeitig auf eine Art aggregierten Wahrheitswert zu bewerten. Aber das macht keinen Sinn, also bekommst du ein ValueError
:
>>> x = numpy.array([0,1])
>>> if x: print("x")
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Aber zumindest der obige Fall sagt Ihnen, dass es fehlgeschlagen ist. Wenn Sie zufällig ein NumPy-Array mit genau einem Element haben, if
"funktioniert" die Anweisung in dem Sinne, dass Sie keinen Fehler erhalten. Wenn dieses eine Element jedoch zufällig 0
(oder 0.0
, oder False
, ...) ist, führt die if
Anweisung fälschlicherweise zu False
:
>>> x = numpy.array([0,])
>>> if x: print("x")
... else: print("No x")
No x
Aber eindeutig x
existiert und ist nicht leer! Dieses Ergebnis ist nicht das, was Sie wollten.
len
kann zu unerwarteten Ergebnissen führenZum Beispiel,
len( numpy.zeros((1,0)) )
Gibt 1 zurück, obwohl das Array keine Elemente enthält.
Wie in den SciPy-FAQ erläutert , ist die richtige Methode in allen Fällen, in denen Sie wissen, dass Sie ein NumPy-Array haben, folgende if x.size
:
>>> x = numpy.array([0,1])
>>> if x.size: print("x")
x
>>> x = numpy.array([0,])
>>> if x.size: print("x")
... else: print("No x")
x
>>> x = numpy.zeros((1,0))
>>> if x.size: print("x")
... else: print("No x")
No x
Wenn Sie nicht sicher sind, ob es sich um ein list
NumPy-Array oder etwas anderes handelt, können Sie diesen Ansatz mit der Antwort von @dubiousjim kombinieren , um sicherzustellen, dass für jeden Typ der richtige Test verwendet wird. Nicht sehr "pythonisch", aber es stellt sich heraus, dass NumPy zumindest in diesem Sinne absichtlich die Pythonizität gebrochen hat.
Wenn Sie mehr tun müssen, als nur zu überprüfen, ob die Eingabe leer ist, und andere NumPy-Funktionen wie Indizierung oder mathematische Operationen verwenden, ist es wahrscheinlich effizienter (und sicherlich häufiger), die Eingabe als NumPy-Array zu erzwingen . Es gibt ein paar nette Funktionen, um dies schnell zu erledigen - am wichtigsten numpy.asarray
. Dies nimmt Ihre Eingabe, führt nichts aus, wenn es sich bereits um ein Array handelt, oder verpackt Ihre Eingabe in ein Array, wenn es sich um eine Liste, ein Tupel usw. handelt, und konvertiert sie optional in die von Ihnen ausgewählte dtype
. Es ist also sehr schnell, wann immer es möglich ist, und es stellt sicher, dass Sie nur davon ausgehen können, dass die Eingabe ein NumPy-Array ist. Normalerweise verwenden wir sogar nur denselben Namen, da die Konvertierung in ein Array nicht außerhalb des aktuellen Bereichs erfolgt :
x = numpy.asarray(x, dtype=numpy.double)
Dadurch x.size
funktioniert die Prüfung in allen Fällen, die ich auf dieser Seite sehe.
numpy
- numpy
eine Bibliothek mit einem sehr spezifischen Anwendungsfall, und sie hat eine andere "natürliche" Definition dessen, was Wahrhaftigkeit auf einem Array für das ist Python-Standard für Container. Es macht Sinn, optimize für diesen Fall in der Weise , dass pathlib
Anwendungen /
zu verketten Pfade statt +
- es ist nicht Standard, aber sinnvoll im Kontext.
if x
als auch für die len(x)
Redewendungen zu unterbrechen - und manchmal kann es sehr schwierig sein, einen Bruch zu erkennen und zu debuggen.
Am besten überprüfen Sie, ob eine Liste leer ist
Zum Beispiel, wenn Folgendes bestanden wurde:
a = []
Wie überprüfe ich, ob a leer ist?
Platzieren Sie die Liste in einem booleschen Kontext (z. B. mit einer if
oder- while
Anweisung). Es wird getestet, False
ob es leer ist und True
ansonsten. Zum Beispiel:
if not a: # do this!
print('a is an empty list')
PEP 8 , der offizielle Python-Styleguide für Python-Code in der Python-Standardbibliothek, behauptet:
Verwenden Sie für Sequenzen (Zeichenfolgen, Listen, Tupel) die Tatsache, dass leere Sequenzen falsch sind.
Yes: if not seq: if seq: No: if len(seq): if not len(seq):
Wir sollten erwarten, dass der Standardbibliothekscode so performant und korrekt wie möglich ist. Aber warum ist das so und warum brauchen wir diese Anleitung?
Ich sehe häufig Code wie diesen von erfahrenen Programmierern, die Python noch nicht kennen:
if len(a) == 0: # Don't do this!
print('a is an empty list')
Und Benutzer fauler Sprachen könnten versucht sein, dies zu tun:
if a == []: # Don't do this!
print('a is an empty list')
Diese sind in ihren jeweiligen anderen Sprachen korrekt. Und das ist in Python sogar semantisch korrekt.
Wir halten es jedoch für nicht pythonisch, da Python diese Semantik über booleschen Zwang direkt in der Schnittstelle des Listenobjekts unterstützt.
Aus den Dokumenten (und beachten Sie insbesondere die Aufnahme der leeren Liste []
):
Standardmäßig wird ein Objekt als wahr betrachtet, es sei denn, seine Klasse definiert entweder eine
__bool__()
Methode, die zurückgibt,False
oder eine__len__()
Methode, die Null zurückgibt, wenn sie mit dem Objekt aufgerufen wird. Hier sind die meisten eingebauten Objekte, die als falsch angesehen werden:
- Konstanten, die als falsch definiert sind:
None
undFalse
.- Null jeden numerischen Typ:
0
,0.0
,0j
,Decimal(0)
,Fraction(0, 1)
- leere Sequenzen und Sammlungen:
''
,()
,[]
,{}
,set()
,range(0)
Und die Dokumentation zum Datenmodell:
Wird aufgerufen, um Wahrheitswerttests und den eingebauten Betrieb zu implementieren
bool()
. sollte zurückkehrenFalse
oderTrue
. Wenn diese Methode nicht definiert ist,__len__()
wird sie aufgerufen, wenn sie definiert ist, und das Objekt wird als wahr betrachtet, wenn sein Ergebnis ungleich Null ist. Wenn eine Klasse weder__len__()
noch definiert__bool__()
, werden alle ihre Instanzen als wahr betrachtet.
und
Wird aufgerufen, um die integrierte Funktion zu implementieren
len()
. Sollte die Länge des Objekts zurückgeben, eine Ganzzahl> = 0. Außerdem wird ein Objekt, das keine__bool__()
Methode definiert und dessen__len__()
Methode Null zurückgibt, in einem booleschen Kontext als falsch betrachtet.
Also stattdessen:
if len(a) == 0: # Don't do this!
print('a is an empty list')
oder dieses:
if a == []: # Don't do this!
print('a is an empty list')
Mach das:
if not a:
print('a is an empty list')
Zahlt es sich aus? (Beachten Sie, dass weniger Zeit für eine gleichwertige Operation besser ist :)
>>> import timeit
>>> min(timeit.repeat(lambda: len([]) == 0, repeat=100))
0.13775854044661884
>>> min(timeit.repeat(lambda: [] == [], repeat=100))
0.0984637276455409
>>> min(timeit.repeat(lambda: not [], repeat=100))
0.07878462291455435
Für die Skalierung sind hier die Kosten für den Aufruf der Funktion und die Erstellung und Rückgabe einer leeren Liste aufgeführt, die Sie möglicherweise von den Kosten für die oben verwendeten Leereprüfungen abziehen:
>>> min(timeit.repeat(lambda: [], repeat=100))
0.07074015751817342
Wir sehen, dass entweder die Überprüfung der Länge mit der integrierten Funktion im len
Vergleich zu 0
oder die Überprüfung anhand einer leeren Liste viel weniger leistungsfähig ist als die Verwendung der integrierten Syntax der Sprache, wie dokumentiert.
Warum?
Zur len(a) == 0
Kontrolle:
Zuerst muss Python die Globals überprüfen, um festzustellen, ob sie len
im Schatten liegen.
Dann muss es die Funktion aufrufen, laden 0
und den Gleichheitsvergleich in Python durchführen (anstelle von C):
>>> import dis
>>> dis.dis(lambda: len([]) == 0)
1 0 LOAD_GLOBAL 0 (len)
2 BUILD_LIST 0
4 CALL_FUNCTION 1
6 LOAD_CONST 1 (0)
8 COMPARE_OP 2 (==)
10 RETURN_VALUE
Und für das muss [] == []
es eine unnötige Liste erstellen und dann erneut die Vergleichsoperation in Pythons virtueller Maschine ausführen (im Gegensatz zu C).
>>> dis.dis(lambda: [] == [])
1 0 BUILD_LIST 0
2 BUILD_LIST 0
4 COMPARE_OP 2 (==)
6 RETURN_VALUE
Die "Pythonic" -Methode ist eine viel einfachere und schnellere Überprüfung, da die Länge der Liste im Objektinstanzheader zwischengespeichert wird:
>>> dis.dis(lambda: not [])
1 0 BUILD_LIST 0
2 UNARY_NOT
4 RETURN_VALUE
Dies ist eine Erweiterung
PyObject
, die dasob_size
Feld hinzufügt . Dies wird nur für Objekte verwendet, die einen Längenbegriff haben. Dieser Typ wird in der Python / C-API nicht häufig angezeigt. Es entspricht den Feldern, die durch die Erweiterung desPyObject_VAR_HEAD
Makros definiert werden.
Aus der c-Quelle in Include / listobject.h :
typedef struct {
PyObject_VAR_HEAD
/* Vector of pointers to list elements. list[0] is ob_item[0], etc. */
PyObject **ob_item;
/* ob_item contains space for 'allocated' elements. The number
* currently in use is ob_size.
* Invariants:
* 0 <= ob_size <= allocated
* len(list) == ob_size
Ich möchte darauf hinweisen, dass dies auch für den nicht leeren Fall gilt, obwohl es ziemlich hässlich ist, wie bei
l=[]
damals%timeit len(l) != 0
90,6 ns ± 8,3 ns,%timeit l != []
55,6 ns ± 3,09,%timeit not not l
38,5 ns ± 0,372. Abernot not l
trotz der dreifachen Geschwindigkeit wird es niemandem Spaß machen . Es sieht lächerlich aus. Aber die Geschwindigkeit gewinnt,
ich nehme an, das Problem besteht darin, mit Zeit zu testen, da dies geradeif l:
ausreicht, aber überraschenderweise%timeit bool(l)
101 ns ± 2,64 ns ergibt. Interessanterweise gibt es keine Möglichkeit, ohne diese Strafe zum Bool zu zwingen.%timeit l
ist nutzlos, da keine Konvertierung stattfinden würde.
IPython-Magie %timeit
ist hier nicht völlig nutzlos:
In [1]: l = []
In [2]: %timeit l
20 ns ± 0.155 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
In [3]: %timeit not l
24.4 ns ± 1.58 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [4]: %timeit not not l
30.1 ns ± 2.16 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
Wir können sehen, dass not
hier für jede weitere ein bisschen lineare Kosten anfallen. Wir wollen die Kosten sehen, ceteris paribus , das heißt, alles andere ist gleich - wo alles andere so weit wie möglich minimiert wird:
In [5]: %timeit if l: pass
22.6 ns ± 0.963 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [6]: %timeit if not l: pass
24.4 ns ± 0.796 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [7]: %timeit if not not l: pass
23.4 ns ± 0.793 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
Schauen wir uns nun den Fall für eine leere Liste an:
In [8]: l = [1]
In [9]: %timeit if l: pass
23.7 ns ± 1.06 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [10]: %timeit if not l: pass
23.6 ns ± 1.64 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [11]: %timeit if not not l: pass
26.3 ns ± 1 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
Was wir hier sehen können, ist, dass es kaum einen Unterschied macht, ob Sie eine tatsächliche bool
an die Bedingungsprüfung oder die Liste selbst übergeben, und wenn überhaupt, ist es schneller, die Liste so wie sie ist zu geben.
Python ist in C geschrieben; es verwendet seine Logik auf der C-Ebene. Alles, was Sie in Python schreiben, ist langsamer. Und es wird wahrscheinlich um Größenordnungen langsamer sein, wenn Sie die in Python integrierten Mechanismen nicht direkt verwenden.
l=[]
damals %timeit len(l) != 0
90,6 ns ± 8,3 ns, %timeit l != []
55,6 ns ± 3,09, %timeit not not l
38,5 ns ± 0,372. Aber not not l
trotz der dreifachen Geschwindigkeit wird es niemandem Spaß machen . Es sieht lächerlich aus. Aber die Geschwindigkeit gewinnt
if l:
ausreicht, aber überraschenderweise %timeit bool(l)
101 ns ± 2,64 ns ergibt. Interessanterweise gibt es keine Möglichkeit, ohne diese Strafe zum Bool zu zwingen. %timeit l
ist nutzlos, da keine Konvertierung stattfinden würde.
Eine leere Liste selbst wird beim Testen von wahren Werten als falsch angesehen (siehe Python-Dokumentation ):
a = []
if a:
print "not empty"
@ Daren Thomas
EDIT: Ein weiterer Punkt gegen das Testen der leeren Liste als False: Was ist mit Polymorphismus? Sie sollten sich nicht darauf verlassen, dass eine Liste eine Liste ist. Es sollte nur wie eine Ente quaken - wie bringen Sie Ihre duckCollection dazu, "False" zu quaken, wenn sie keine Elemente enthält?
Ihre duckCollection sollte implementieren __nonzero__
oder __len__
so, wenn a: ohne Probleme funktioniert.
[] == False
zu False ausgewertet wird
bool()
. bool([]) == False
wird True
wie erwartet auswerten .
Patricks (akzeptierte) Antwort ist richtig: if not a:
ist der richtige Weg, es zu tun. Harley Holcombes Antwort ist richtig, dass dies im PEP 8 Style Guide steht. Keine der Antworten erklärt jedoch, warum es eine gute Idee ist, der Redewendung zu folgen - auch wenn Sie persönlich feststellen, dass sie für Ruby-Benutzer oder was auch immer nicht explizit genug oder verwirrend ist.
Python-Code und die Python-Community haben sehr starke Redewendungen. Wenn Sie diesen Redewendungen folgen, ist Ihr Code für alle, die mit Python vertraut sind, leichter zu lesen. Und wenn Sie diese Redewendungen verletzen, ist das ein starkes Signal.
Es ist wahr, dass if not a:
leere Listen nicht von None
oder numerische 0 oder leere Tupel oder leere, vom Benutzer erstellte Sammlungstypen oder leere, vom Benutzer erstellte nicht ganz Sammlungstypen oder ein NumPy-Array mit einem Element, das als Skalare mit Falsey fungiert, unterschieden werden Werte usw. Und manchmal ist es wichtig, dies ausdrücklich zu erwähnen. In diesem Fall wissen Sie, worüber Sie explizit sprechen möchten, und können genau das testen. if not a and a is not None:
Bedeutet beispielsweise "alles Falsche außer Keine", während if len(a) != 0:
"nur leere Sequenzen - und alles außer einer Sequenz ist hier ein Fehler" und so weiter bedeutet. Dies testet nicht nur genau das, was Sie testen möchten, sondern signalisiert dem Leser auch, dass dieser Test wichtig ist.
Aber wenn Sie nichts explizites haben, führt etwas anderes if not a:
den Leser in die Irre. Sie signalisieren etwas so Wichtiges, wenn es nicht ist. (Sie können auch sein machen den Code weniger flexibel, oder langsamer, oder was auch immer, aber das ist alles weniger wichtig ist .) Und wenn Sie gewohnheitsmäßig die Leser wie diese täuschen, dann , wenn Sie tun müssen , eine Unterscheidung zu machen, es geht unbemerkt , weil passieren Sie haben überall in Ihrem Code "Wolf geweint".
Niemand scheint sich damit befasst zu haben, Ihre Notwendigkeit in Frage zu stellen, die Liste überhaupt zu testen. Da Sie keinen zusätzlichen Kontext angegeben haben, kann ich mir vorstellen, dass Sie diese Überprüfung möglicherweise gar nicht erst durchführen müssen, aber mit der Listenverarbeitung in Python nicht vertraut sind.
Ich würde argumentieren, dass der pythonischste Weg darin besteht, überhaupt nicht zu überprüfen, sondern nur die Liste zu verarbeiten. Auf diese Weise wird es das Richtige tun, ob leer oder voll.
a = []
for item in a:
<do something with item>
<rest of code>
Dies hat den Vorteil, dass alle Inhalte von a gehandhabt werden können, ohne dass eine spezifische Überprüfung der Leere erforderlich ist. Wenn a leer ist, wird der abhängige Block nicht ausgeführt und der Interpreter fällt in die nächste Zeile durch.
Wenn Sie das Array tatsächlich auf Leere überprüfen müssen, sind die anderen Antworten ausreichend.
<rest of code>
, das das Ergebnis der for
Schleife verwenden könnte? Oder direkt einige Werte in verwenden a
? Wenn das Skript für die Ausführung mit streng kontrollierten Eingaben ausgelegt ist, ist die Überprüfung möglicherweise etwas unnötig. In den meisten Fällen variiert die Eingabe jedoch, und eine Überprüfung ist in der Regel besser.
len()
ist eine O (1) -Operation für Python-Listen, Strings, Dicts und Sets. Python verfolgt intern die Anzahl der Elemente in diesen Containern.
JavaScript hat eine ähnliche Vorstellung von Wahrheit / Falschheit .
Ich hatte geschrieben:
if isinstance(a, (list, some, other, types, i, accept)) and not a:
do_stuff
welches mit -1 gewählt wurde. Ich bin mir nicht sicher, ob dies daran liegt, dass die Leser Einwände gegen die Strategie erhoben oder der Meinung waren, dass die Antwort in der vorgestellten Form nicht hilfreich war. Ich werde so tun, als wäre es das letztere, da - was auch immer als "pythonisch" gilt - dies die richtige Strategie ist. Sofern Sie dies nicht bereits ausgeschlossen haben oder bereit sind, Fälle zu behandeln, in denen dies a
beispielsweise der Fall ist, False
benötigen Sie einen Test, der restriktiver ist als nur if not a:
. Sie könnten so etwas verwenden:
if isinstance(a, numpy.ndarray) and not a.size:
do_stuff
elif isinstance(a, collections.Sized) and not a:
do_stuff
Der erste Test ist eine Antwort auf die Antwort von @ Mike oben. Die dritte Zeile könnte auch ersetzt werden durch:
elif isinstance(a, (list, tuple)) and not a:
Wenn Sie nur Instanzen bestimmter Typen (und ihrer Untertypen) akzeptieren möchten, oder mit:
elif isinstance(a, (list, tuple)) and not len(a):
Sie können ohne die explizite Typprüfung davonkommen, aber nur, wenn der umgebende Kontext Ihnen bereits versichert, dass dies a
ein Wert der Typen ist, für die Sie bereit sind, oder wenn Sie sicher sind, dass Typen, für die Sie nicht bereit sind, funktionieren um Fehler auszulösen (z. B. TypeError
wenn Sie len
einen Wert aufrufen , für den er nicht definiert ist), den Sie verarbeiten möchten. Im Allgemeinen scheinen die "pythonischen" Konventionen diesen letzten Weg zu gehen. Drücke es wie eine Ente und lass es einen DuckError auslösen, wenn es nicht weiß, wie man quakt. Sie müssen sich jedoch noch überlegen, welche Art von Annahmen Sie treffen und ob die Fälle, auf die Sie nicht vorbereitet sind, wirklich an den richtigen Stellen fehlerhaft sind. Die Numpy-Arrays sind ein gutes Beispiel, auf das man sich nur blind verlassen kannlen
oder der boolesche Typecast macht möglicherweise nicht genau das, was Sie erwarten.
collections.abc.Sized
oder collections.abc.Sequence
, aber es könnte eines sein, auf das Sie selbst und register(list)
auf schreiben . Wenn Sie tatsächlich Code haben, bei dem es wichtig ist, leere von anderen Falseys zu unterscheiden und auch Listen und Tupel von anderen Sequenzen zu unterscheiden, dann ist dies richtig - aber ich glaube nicht, dass Sie einen solchen Code haben.
[]
und nicht etwas Falsches eines anderen Typs, dann ist dies sicherlich if a == []:
erforderlich, anstatt mit isinstance herumzuspielen.
==
. Auf den ersten Blick kann ich keine identifizieren []
. [] == ()
zum Beispiel kehrt zurück False
. Aber zum Beispiel frozenset()==set()
kehrt zurück True
. Es lohnt sich also, zumindest darüber nachzudenken, ob ein unerwünschter Typ dazu gezwungen werden könnte []
(oder umgekehrt) a == []
.
Aus der Dokumentation zur Wahrheitsprüfung:
Alle anderen als die hier aufgeführten Werte werden berücksichtigt True
None
False
0
, 0.0
, 0j
.''
, ()
, []
.{}
.__bool__()
oder __len__()
Methode definiert , wenn diese Methode die Ganzzahl Null oder den Bool-Wert zurückgibt False
.Wie man sehen kann, leere Liste []
ist falsy , so zu tun , was zu einem Booleschen Wert Sounds effizientesten durchgeführt werden würde:
if not a:
print('"a" is empty!')
assert(not myList)
. Wenn Sie auch behaupten möchten, dass das Objekt a ist list
, können Sie verwenden assertIsInstance()
.
Hier sind einige Möglichkeiten, wie Sie überprüfen können, ob eine Liste leer ist:
a = [] #the list
1) Der ziemlich einfache pythonische Weg:
if not a:
print("a is empty")
In Python werden leere Container wie Listen, Tupel, Mengen, Dikte, Variablen usw. als angesehen False
. Man könnte die Liste einfach als Prädikat behandeln ( Rückgabe eines Booleschen Wertes ). Und ein True
Wert würde anzeigen, dass er nicht leer ist.
2) Ein sehr expliziter Weg: Verwenden Sie die len()
, um die Länge zu ermitteln und zu überprüfen, ob sie gleich ist 0
:
if len(a) == 0:
print("a is empty")
3) Oder vergleichen Sie es mit einer anonymen leeren Liste:
if a == []:
print("a is empty")
4) Eine andere, aber alberne Art zu tun ist exception
und iter()
:
try:
next(iter(a))
# list has elements
except StopIteration:
print("Error: a is empty")
Ich bevorzuge folgendes:
if a == []:
print "The list is empty."
if not a:
und bricht leichter. Bitte tu es nicht.
() == []
ist auch gleich falsch. Obwohl mir gefällt, wie diese Implementierung if not a:
alle Fälle abdeckt, sollte Ihr Beispiel ausreichen, wenn Sie definitiv eine Liste erwarten.
def list_test (L):
if L is None : print('list is None')
elif not L : print('list is empty')
else: print('list has %d elements' % len(L))
list_test(None)
list_test([])
list_test([1,2,3])
Es ist manchmal gut, None
getrennt auf Leere zu prüfen, da dies zwei verschiedene Zustände sind. Der obige Code erzeugt die folgende Ausgabe:
list is None
list is empty
list has 3 elements
Obwohl es nichts wert ist, None
was falsch ist. Wenn Sie also den Test für None
-ness nicht trennen möchten , müssen Sie das nicht tun.
def list_test2 (L):
if not L : print('list is empty')
else: print('list has %d elements' % len(L))
list_test2(None)
list_test2([])
list_test2([1,2,3])
produziert erwartet
list is empty
list is empty
list has 3 elements
Viele Antworten wurden gegeben, und viele von ihnen sind ziemlich gut. Ich wollte nur hinzufügen, dass der Scheck
not a
wird auch für None
und andere Arten von leeren Strukturen passieren . Wenn Sie wirklich nach einer leeren Liste suchen möchten, können Sie dies tun:
if isinstance(a, list) and len(a)==0:
print("Received an empty list")
a
es sich nicht um eine Liste handelt und a
keine Methode __len__
implementiert ist. Ich würde empfehlen:if isinstance(obj, list): if len(obj) == 0: print '...'
and
ist in Python faul. Nichts danach and
wird ausgeführt, wenn die vorherige Bedingung and
falsch ist.
wir könnten ein einfaches verwenden, wenn sonst:
item_list=[]
if len(item_list) == 0:
print("list is empty")
else:
print("list is not empty")
Wenn Sie überprüfen möchten, ob eine Liste leer ist:
l = []
if l:
# do your stuff.
Wenn Sie überprüfen möchten, ob alle Werte in der Liste leer sind. Es wird jedoch True
für eine leere Liste sein:
l = ["", False, 0, '', [], {}, ()]
if all(bool(x) for x in l):
# do your stuff.
Wenn Sie beide Fälle zusammen verwenden möchten:
def empty_list(lst):
if len(lst) == 0:
return False
else:
return all(bool(x) for x in l)
Jetzt können Sie verwenden:
if empty_list(lst):
# do your stuff.
Da ich mich von der Lösung von @ dubiousjim inspirieren lasse, schlage ich vor, zusätzlich zu prüfen, ob es sich um etwas Iterierbares handelt
import collections
def is_empty(a):
return not a and isinstance(a, collections.Iterable)
Hinweis: Eine Zeichenfolge wird als iterierbar betrachtet. - Hinzufügen, and not isinstance(a,(str,unicode))
wenn die leere Zeichenfolge ausgeschlossen werden soll
Prüfung:
>>> is_empty('sss')
False
>>> is_empty(555)
False
>>> is_empty(0)
False
>>> is_empty('')
True
>>> is_empty([3])
False
>>> is_empty([])
True
>>> is_empty({})
True
>>> is_empty(())
True
if a:
wäre, wäre es, weil ich eine Ausnahme wollte, wenn a
es keine Art Container wäre. (Als iterable können auch Iteratoren verwendet werden, die nicht sinnvoll auf Leere getestet werden können.)
print('not empty' if a else 'empty')
etwas praktischer:
a.pop() if a else None
und Shertest-Version:
if a: a.pop()
Ab Python3 können Sie verwenden
a == []
um zu überprüfen, ob die Liste leer ist
EDIT: Dies funktioniert auch mit Python2.7.
Ich bin mir nicht sicher, warum es so viele komplizierte Antworten gibt. Es ist ziemlich klar und unkompliziert
a
leer ist oder nicht.
pythonic
a==[]
, wird true auf dem Python-Terminal gedruckt, wenn a leer ist. Andernfalls wird False ausgegeben. Sie können dies in einer if-Bedingung auch alsif(a==[])
Sie können sogar versuchen, bool () wie folgt zu verwenden
a = [1,2,3];
print bool(a); # it will return True
a = [];
print bool(a); # it will return False
Ich liebe diese Art der Checkliste ist leer oder nicht.
Sehr praktisch und nützlich.
bool()
wird eine Python-Variable in einen Booleschen Wert konvertiert, sodass Sie die Wahrhaftigkeit oder Falschheit eines Werts speichern können , ohne eine if-Anweisung verwenden zu müssen. Ich denke, es ist weniger lesbar als nur eine Bedingung wie die akzeptierte Antwort zu verwenden, aber ich bin sicher, dass es andere gute Anwendungsfälle dafür gibt.
Verwenden Sie einfach is_empty () oder machen Sie eine Funktion wie: -
def is_empty(any_structure):
if any_structure:
print('Structure is not empty.')
return True
else:
print('Structure is empty.')
return False
Es kann für jede Datenstruktur wie eine Liste, Tupel, ein Wörterbuch und vieles mehr verwendet werden. Mit diesen können Sie es viele Male mit nur aufrufen is_empty(any_structure)
.
is_empty
deutet darauf hin, dass es etwas zurückgibt. Aber wenn es so wäre, wäre das einfach etwas bool(any_structure)
, das Sie stattdessen verwenden sollten ( wenn Sie überhaupt ein brauchen bool
).
bool
, die (auch) Nachrichten in die Standardausgabe druckt?
bool
. Du hast die Wahl. Ich schreibe beide, damit Sie zwischen ihnen wählen können.
Ein einfacher Weg ist zu überprüfen, ob die Länge gleich Null ist.
if len(a) == 0:
print("a is empty")
Der Wahrheitswert einer leeren Liste ist, False
während dies für eine nicht leere Liste der Fall ist True
.
Was mich hierher gebracht hat, ist ein spezieller Anwendungsfall: Ich wollte eigentlich eine Funktion , die mir sagt, ob eine Liste leer ist oder nicht. Ich wollte vermeiden, hier meine eigene Funktion zu schreiben oder einen Lambda-Ausdruck zu verwenden (weil es so schien, als ob es einfach genug sein sollte):
foo = itertools.takewhile(is_not_empty, (f(x) for x in itertools.count(1)))
Und natürlich gibt es einen sehr natürlichen Weg, dies zu tun:
foo = itertools.takewhile(bool, (f(x) for x in itertools.count(1)))
Natürlich müssen nicht verwendet werden bool
in if
(dh if bool(L):
) , weil es impliziert wird . Aber für die Fälle, in denen "nicht leer" explizit als Funktion benötigt wird, bool
ist dies die beste Wahl.
Um zu überprüfen, ob eine Liste leer ist oder nicht, haben Sie zwei Möglichkeiten. Aber denken Sie daran, wir sollten es vermeiden, explizit nach einem Sequenztyp zu suchen (es ist ein
less pythonic
Weg):
def enquiry(list1):
if len(list1) == 0:
return 0
else:
return 1
# ––––––––––––––––––––––––––––––––
list1 = []
if enquiry(list1):
print ("The list isn't empty")
else:
print("The list is Empty")
# Result: "The list is Empty".
Der zweite Weg ist ein
more pythonic
Eins. Diese Methode ist eine implizite Methode zur Überprüfung und weitaus bevorzugter als die vorherige.
def enquiry(list1):
if not list1:
return True
else:
return False
# ––––––––––––––––––––––––––––––––
list1 = []
if enquiry(list1):
print ("The list is Empty")
else:
print ("The list isn't empty")
# Result: "The list is Empty"
Hoffe das hilft.