Wie überprüfe ich, ob eine Liste leer ist?

3234

Zum Beispiel, wenn Folgendes bestanden wurde:

a = []

Wie überprüfe ich, ob aes leer ist?

Strahl
quelle

Antworten:

5494
if not a:
  print("List is empty")

Die implizite Booleschheit des Leeren zu verwenden, listist ziemlich pythonisch.

Patrick
quelle
1130
Teufelsanwalt spielen. Ich verstehe nicht, warum diese Redewendung als pythonisch angesehen wird. "Explizit ist besser als implizit", richtig? Diese Überprüfung scheint nicht sehr explizit zu sein, was überprüft wird.
James McMahon
222
@JamesMcMahon - es ist ein Kompromiss zwischen expliziter und typischer Flexibilität. Im Allgemeinen bedeutet "explizit sein", keine "magischen" Dinge zu tun. Auf der anderen Seite bedeutet "Ententypisierung", mit allgemeineren Schnittstellen zu arbeiten, anstatt explizit nach Typen zu suchen. So etwas wie 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__ )
andrew cooke
38
Diese Methode funktioniert nicht bei Numpy-Arrays. Ich denke also, wenn len (a) == 0 sowohl in Bezug auf "Ententypisierung" als auch implizit vorzuziehen ist.
Mr.WorshipMe
10
Die kanonische Methode, um festzustellen, ob ein Array in C leer ist, besteht darin, das erste Element zu dereferenzieren und zu prüfen, ob es null ist, vorausgesetzt, ein Array ist nicht terminiert. Andernfalls ist der Vergleich seiner Länge mit Null völlig ineffizient, wenn das Array eine signifikante Größe hat. Außerdem würden Sie normalerweise keinen Speicher für ein leeres Array zuweisen (der Zeiger bleibt null), sodass es keinen Sinn macht, zu versuchen, seine Länge zu ermitteln. Ich sage nicht, dass len (a) == 0 kein guter Weg ist, es zu tun, es schreit mir einfach nicht 'C', wenn ich es sehe.
Sleblanc
6
@BrennenSprimont, Wenn es nicht nullterminiert ist, kennen Sie bereits die Länge, ob es in einer separaten Variablen gespeichert ist oder Ihr Array in einen Container eingeschlossen ist, der die Länge verfolgt. C ++, Java, C # haben solche Container und implementieren eine "Längen" -Methode effizient. C hat so etwas nicht , du musst dein eigenes rollen. Statisch zugewiesene C-Arrays sind nur Zeiger auf einen Speicherplatz, der garantiert über genügend Speicherplatz verfügt, um die von Ihnen angeforderte Datenmenge zu speichern. In C ist nichts eingebaut, was Sie wissen lässt, wie viel Sie diesen Raum bereits gefüllt haben.
Sleblanc
1159

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):
Harley Holcombe
quelle
49
Der zweite Weg scheint besser zu sein, wenn Sie signalisieren möchten, dass seqes sich um ein listähnliches Objekt handelt.
BallpointBen
5
@BallpointBen, der, wie Pythonismus-Befürworter sagen würden, so weit wie möglich implizit in der Art und Weise sein sollte, wie die Variable benannt wird
axolotl
9
@BallpointBen versuchen Python mit Typ - Hinting für die Signalisierung , was eine Variable sein sollte. Es wurde in 3.5 eingeführt.
Boris
8
numpy hat diese Redewendung gebrochen ... seq = numpy.array ([1,2,3]), gefolgt von seq, wenn nicht, löst eine Ausnahme aus. "ValueError: Der Wahrheitswert eines Arrays mit mehr als einem Element ist nicht eindeutig. Verwenden Sie a.any () oder a.all () "
Mr.WorshipMe
2
@ Jeronimo: Ich glaube, das ist eine lxml-spezifische Warnung.
Harley Holcombe
767

Ich bevorzuge es ausdrücklich:

if len(li) == 0:
    print('the list is empty')

Auf diese Weise ist zu 100% klar, dass lies 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 lies sich um eine boolesche Variable handelt.

Jabba
quelle
91
Es ist hässlich und unpythonisch zu überprüfen, ob die Länge einer Liste gleich Null ist, anstatt nur zu überprüfen, ob die Liste falsch ist. Jeder, der mit Python vertraut ist, wird nicht denken, dass er überhaupt liein Idiot ist, und es ist ihm egal. Wenn es wichtig ist, sollten Sie einen Kommentar hinzufügen, nicht mehr Code.
Carl Smith
21
Dies scheint ein unnötig präziser Test zu sein, der oft langsamer und meiner Meinung nach immer weniger lesbar ist. Anstatt die Größe von etwas Leerem zu überprüfen, prüfen Sie doch einfach, ob es leer ist.
John B
34
Der Grund, warum dies schlecht ist (und dass das Verletzen von Redewendungen in einer Sprache mit starken Redewendungen wie Python im Allgemeinen schlecht ist), ist, dass es dem Leser signalisiert, dass Sie die Länge aus irgendeinem Grund speziell überprüfen (z. B. weil Sie Noneoder wollen 0eine 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.
Abarnert
18
Ich denke, das verlängert den Code nur unnötig. Warum nicht noch "expliziter" mit if bool(len(li) == 0) is True:?
Augurar
11
@Jabba ist in vielen Fällen O (1) (bei denen Sie mit den integrierten Datentypen arbeiten), aber darauf können Sie sich einfach nicht verlassen. Möglicherweise arbeiten Sie mit einem benutzerdefinierten Datentyp, der diese Eigenschaft nicht hat. Sie können diesen benutzerdefinierten Datentyp auch später hinzufügen, nachdem Sie diesen Code bereits geschrieben haben.
Ralokt
324

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.

Andere Methoden funktionieren nicht für NumPy-Arrays

Sie müssen mit NumPy-Arrays vorsichtig sein, da andere Methoden, die für lists 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.

Der "pythonische" Weg funktioniert nicht: Teil 1

Die "pythonische" Methode schlägt bei NumPy-Arrays fehl, da NumPy versucht, das Array in ein Array von bools umzuwandeln , und if xversucht, alle diese bools 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()

Der "pythonische" Weg funktioniert nicht: Teil 2

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 ifAnweisung fälschlicherweise zu False:

>>> x = numpy.array([0,])
>>> if x: print("x")
... else: print("No x")
No x

Aber eindeutig xexistiert und ist nicht leer! Dieses Ergebnis ist nicht das, was Sie wollten.

Die Verwendung lenkann zu unerwarteten Ergebnissen führen

Zum Beispiel,

len( numpy.zeros((1,0)) )

Gibt 1 zurück, obwohl das Array keine Elemente enthält.

Der numpythonische Weg

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 listNumPy-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.sizefunktioniert die Prüfung in allen Fällen, die ich auf dieser Seite sehe.

Mike
quelle
62
Es ist erwähnenswert, dass dies kein Fehler in Python ist, sondern eine absichtliche Vertragsunterbrechung durch numpy- numpyeine 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 pathlibAnwendungen /zu verketten Pfade statt +- es ist nicht Standard, aber sinnvoll im Kontext.
Gareth Latty
9
Einverstanden. Mein Punkt ist nur, dass es wichtig ist, sich daran zu erinnern, dass Numpy die Entscheidung getroffen hat, das Tippen von Enten sowohl für die sehr verbreiteten if xals auch für die len(x)Redewendungen zu unterbrechen - und manchmal kann es sehr schwierig sein, einen Bruch zu erkennen und zu debuggen.
Mike
22
Ich weiß für mich nicht, ob eine Methode namens len (x) die Array-Länge aufgrund von Annahmen nicht zurückgibt, deren Name schlecht entworfen ist.
Dalton
11
Diese Frage hat nichts mit numpy Arrays zu tun
pppery
19
@ppperry Ja, die ursprüngliche Frage betraf nicht Numpy-Arrays, aber wenn Sie mit diesen und möglicherweise von Enten eingegebenen Argumenten arbeiten, wird diese Frage sehr relevant.
Peterhil
223

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?

Kurze Antwort:

Platzieren Sie die Liste in einem booleschen Kontext (z. B. mit einer ifoder- whileAnweisung). Es wird getestet, Falseob es leer ist und Trueansonsten. Zum Beispiel:

if not a:                           # do this!
    print('a is an empty list')

PEP 8

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?

Erläuterung

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, Falseoder 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: Noneund False.
  • 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:

object.__bool__(self)

Wird aufgerufen, um Wahrheitswerttests und den eingebauten Betrieb zu implementieren bool(). sollte zurückkehren Falseoder True. 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

object.__len__(self)

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')

Das zu tun, was Pythonic normalerweise in der Leistung auszahlt:

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 lenVergleich 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) == 0Kontrolle:

Zuerst muss Python die Globals überprüfen, um festzustellen, ob sie lenim Schatten liegen.

Dann muss es die Funktion aufrufen, laden 0und 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

Nachweise aus der C-Quelle und Dokumentation

PyVarObject

Dies ist eine Erweiterung PyObject, die das ob_sizeFeld 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 des PyObject_VAR_HEADMakros 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

Antwort auf Kommentare:

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) != 090,6 ns ± 8,3 ns, %timeit l != []55,6 ns ± 3,09, %timeit not not l38,5 ns ± 0,372. Aber not not ltrotz 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 gerade 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 list nutzlos, da keine Konvertierung stattfinden würde.

IPython-Magie %timeitist 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 nothier 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 boolan 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.

Aaron Hall
quelle
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) != 090,6 ns ± 8,3 ns, %timeit l != []55,6 ns ± 3,09, %timeit not not l38,5 ns ± 0,372. Aber not not ltrotz der dreifachen Geschwindigkeit wird es niemandem Spaß machen . Es sieht lächerlich aus. Aber die Geschwindigkeit gewinnt
Gregory Morse
Ich nehme an, das Problem besteht darin, mit Zeit zu testen, da dies gerade 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 list nutzlos, da keine Konvertierung stattfinden würde.
Gregory Morse
138

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.

Peter Hoffmann
quelle
Seltsam, wie [] == Falsezu False ausgewertet wird
information_interchange
@information_interchange Wenn Sie die Richtigkeit eines Werts explizit überprüfen möchten, verwenden Sie bool(). bool([]) == Falsewird Truewie erwartet auswerten .
August
103

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 Noneoder 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".

abarnert
quelle
78

Warum überhaupt nachsehen?

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.

MrWonderful
quelle
3
Die Sache ist, zu überprüfen, ob die Liste leer ist, ist ziemlich wichtig, zumindest für mich. Haben Sie darüber nachgedacht, ob ein Skript enthalten ist <rest of code>, das das Ergebnis der forSchleife 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.
Amarth Gûl
Mit Respekt, nein. Was ich in Betracht zog, war jemand, der nicht genug über Python wusste, um zu wissen, dass "if <list>:" die richtige Antwort war, und fragte, wie man nach einer leeren Liste sucht. Dann bemerke ich eine Menge Antworten, die unterschiedliche Meinungen boten, aber keine schien das ursprüngliche Bedürfnis anzusprechen. Das habe ich mit meiner Antwort versucht - lassen Sie sie die Notwendigkeit prüfen, bevor Sie fortfahren. Ich glaube, ich habe dies in meiner Antwort ausdrücklich vorgeschlagen.
MrWonderful
AmarthGûl @ - Wie könnte man bekommen , die Ergebnisse aus der for - Schleife , um das Skript innerhalb <Code ruhen> verarbeitet werden? In einer Liste vielleicht? Oder vielleicht ein Diktat? In diesem Fall gilt dieselbe Logik. Ich verstehe nicht, wie sich die Eingabe von Variablen auf einen vernünftig gestalteten Code auswirken kann, bei dem die Verarbeitung einer leeren Liste eine schlechte Idee wäre.
MrWonderful
Ein bisschen alt, aber wenn Sie nur überprüft haben, ob die Liste leer ist, wiederholt Ihr Code für eine nicht leere Liste den Vorgang immer wieder, wenn OP einfach nach einer Überprüfungsoperation sucht. Stellen Sie sich ein Worst-Case-Szenario für diesen Code vor, wenn sich n der Unendlichkeit nähert ...
DJK
7
@DJK - Nein, ich denke du vermisst es immer noch. Vermutlich möchten Sie etwas mit einer Liste tun, wenn Sie eine haben. Was würden Sie anders machen, wenn es leer wäre? Früh zurück? Was ist, wenn es nicht leer ist? verarbeiten? Der Punkt ist jedoch, dass Sie wahrscheinlich nicht nach einer leeren Liste suchen müssen, sondern nur darüber iterieren und alles tun müssen, was Sie mit den Elementen tun wollten . Wenn es keine Elemente gibt, fallen Sie durch. Wenn es Elemente gibt, verarbeiten Sie diese nach Bedarf. Es geht NICHT darum, das Beispiel für eine leere Prüfung zu verwenden, sondern überhaupt nicht zu prüfen. Verarbeiten Sie einfach die Liste.
MrWonderful
40

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 abeispielsweise der Fall ist, Falsebenö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 aein 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. TypeErrorwenn Sie leneinen 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.

zweifelhaft
quelle
3
Es ist ziemlich selten, dass Sie eine vollständige Liste von 6 Typen haben, die Sie akzeptieren möchten und für keine anderen Typen flexibel sind. Wenn Sie so etwas brauchen, möchten Sie wahrscheinlich ein ABC. In diesem Fall wäre es wahrscheinlich eines der stdlib-ABCs, wie collections.abc.Sizedoder 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.
Abarnert
13
Der Grund, warum die Leute das nicht mögen, ist, dass es in den meisten Fällen völlig unnötig ist. Python ist eine Sprache vom Typ Ente, und diese Ebene der defensiven Codierung behindert dies aktiv. Die Idee hinter Pythons Typsystem ist, dass die Dinge so lange funktionieren sollten, wie das übergebene Objekt in Funktionen funktioniert, wie es benötigt wird. Durch explizite Typprüfungen zwingen Sie den Anrufer, bestimmte Typen zu verwenden, was genau der Sprache entspricht. Während gelegentlich solche Dinge notwendig sind (ausgenommen, dass Zeichenfolgen nicht als Sequenzen behandelt werden), sind solche Fälle selten und fast immer am besten als schwarze Listen.
Gareth Latty
1
Wenn Sie wirklich überprüfen möchten, ob der Wert genau ist []und nicht etwas Falsches eines anderen Typs, dann ist dies sicherlich if a == []:erforderlich, anstatt mit isinstance herumzuspielen.
RemcoGerlich
2
Es gibt jedoch einige automatische Zwänge ==. 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 == [].
Dubiousjim
@RemcoGerlich - isinstance () ist immer noch vorzuziehen, anstatt eine leere Liste zum Vergleichen zu erstellen. Wie ein anderer hervorhob, kann der Gleichheitsoperator auch eine implizite Konvertierung einiger Typen aufrufen, was unerwünscht sein kann. Es gibt keinen Grund, jemals "a == []" zu codieren, und dieser Code würde definitiv als Fehler in einer Codeüberprüfung gekennzeichnet sein, an der ich teilgenommen habe , "sondern" gute Programmiertechnik ".
MrWonderful
29

Aus der Dokumentation zur Wahrheitsprüfung:

Alle anderen als die hier aufgeführten Werte werden berücksichtigt True

  • None
  • False
  • Null von beliebigen numerischen Typs, zum Beispiel 0, 0.0, 0j.
  • jede leere Sequenz, zum Beispiel, '', (), [].
  • jede leere Zuordnung zum Beispiel {}.
  • Instanzen von benutzerdefinierten Klassen, wenn die Klasse eine __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!')
Sнаđошƒаӽ
quelle
@DJ_Stuffy_K behaupten, was in Unit-Tests eine leere Liste? Einfach benutzen assert(not myList). Wenn Sie auch behaupten möchten, dass das Objekt a ist list, können Sie verwenden assertIsInstance().
Sнаđошƒаӽ
24

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 TrueWert 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 exceptionund iter():

try:
    next(iter(a))
    # list has elements
except StopIteration:
    print("Error: a is empty")
Inconnu
quelle
20

Ich bevorzuge folgendes:

if a == []:
   print "The list is empty."
verix
quelle
37
Dies wird langsamer, da Sie unnötigerweise eine zusätzliche leere Liste instanziieren.
Carl Meyer
32
Dies ist weniger lesbar als if not a:und bricht leichter. Bitte tu es nicht.
devsnd
Es gibt einen guten Punkt, der früher gemacht wurde, () == []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.
Ein Stern
19

Methode 1 (bevorzugt):

if not a : 
   print ("Empty") 

Methode 2:

if len(a) == 0 :
   print( "Empty" )

Methode 3:

if a == [] :
  print ("Empty")
Vikrant
quelle
12
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, Nonegetrennt 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, Nonewas 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
Tagar
quelle
8

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 Noneund 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")
HackerBoss
quelle
Es ist möglich, dass dies eine Ausnahme auslöst, wenn aes sich nicht um eine Liste handelt und akeine Methode __len__implementiert ist. Ich würde empfehlen:if isinstance(obj, list): if len(obj) == 0: print '...'
Sven Krüger
4
@ SvenKrüger nein. Der Operator andist in Python faul. Nichts danach andwird ausgeführt, wenn die vorherige Bedingung andfalsch ist.
ElmoVanKielmo
7

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")
l. zhang
quelle
5
-1 - Um Verwirrung zu vermeiden, verwenden Sie keine reservierten Wörter für Variablennamen. Andernfalls kann es beim nächsten Aufruf zu einem überraschenden Verhalten kommen, z. B. "list ()" ... so etwas wie "TypeError: 'list' object is nicht aufrufbar "oder so.
MrWonderful
6

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 Truefü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.
Rahul
quelle
1
all (bool (x) für x in l) ist wahr für eine leere Liste
gberger
5

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
AndreyS Scherbakov
quelle
1
Overbroad; Dabei wird nur gefragt, ob eine Liste leer ist und nicht, ob etwas leer ist.
pppery
1
Wenn ich nicht zufrieden if a:wäre, wäre es, weil ich eine Ausnahme wollte, wenn aes keine Art Container wäre. (Als iterable können auch Iteratoren verwendet werden, die nicht sinnvoll auf Leere getestet werden können.)
Davis Herring
5
print('not empty' if a else 'empty')

etwas praktischer:

a.pop() if a else None

und Shertest-Version:

if a: a.pop() 
Andrey Suglobov
quelle
4

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

Tessaracter
quelle
1
Bitte geben Sie weitere Erklärungen dazu, wie es funktioniert, ohne "wenn" zu schreiben.
Ganeshdeshmukh
3
Dies ist weder ein Python noch ein vollständiges Beispiel. Außerdem wird bei jeder Begegnung eine leere Liste instanziiert. Tu das nicht.
MrWonderful
@ MrWonderful instanziiert nicht jedes Mal eine leere Liste. Es wird nur überprüft, ob die vorhandene Liste aleer ist oder nicht.
Tessaracter
@ MrWonderful Ich verstehe nicht, was es machtpythonic
Tessaracter
@ganeshdeshmukh, wenn Sie es verwenden 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==[])
Tessaracter
3

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.

Sunil Lulla
quelle
4
Für diejenigen (wie ich), die es nicht wussten, 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.
Galen Long
Dies ist in einem Ausdruck verwendbar und knapper.
Qneill
3

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).

Vineet Jain
quelle
3
Der Name is_emptydeutet 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).
Davis Herring
4
Warum wollen wir eine Variation davon bool, die (auch) Nachrichten in die Standardausgabe druckt?
Davis Herring
@DavisHerring Wir haben immer zwei Möglichkeiten, zuerst mit der Funktion zu drucken, andere verwenden die Rückgabevariable bool. Du hast die Wahl. Ich schreibe beide, damit Sie zwischen ihnen wählen können.
Vineet Jain
3

Ein einfacher Weg ist zu überprüfen, ob die Länge gleich Null ist.

if len(a) == 0:
    print("a is empty")
Ashiq Imran
quelle
1

Der Wahrheitswert einer leeren Liste ist, Falsewährend dies für eine nicht leere Liste der Fall ist True.

MiloMinderbinder
quelle
1

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 boolin 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, boolist dies die beste Wahl.

Vedran Šego
quelle
1

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 pythonicWeg):

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 pythonicEins. 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.

Andy
quelle