3227 Stimmen

Wie kann ich prüfen, ob eine Liste leer ist?

Zum Beispiel, wenn Sie das folgende übergeben:

a = []

Wie kann ich überprüfen, ob a leer ist?

181voto

Peter Hoffmann Punkte 52200

Eine leere Liste wird bei der Wahrheitswertprüfung selbst 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 Falsch: Was ist mit Polymorphismus? Man sollte sich nicht darauf verlassen eine Liste eine Liste ist. Sie sollte einfach quaken wie eine Ente - wie wollen Sie deine duckCollection dazu bringen, zu quaken ''Falsch'', wenn sie keine Elemente hat?

Ihre duckCollection sollte implementieren __nonzero__ o __len__ damit die if a: ohne Probleme funktioniert.

2 Stimmen

Seltsam, wie [] == False wird zu False ausgewertet, obwohl

7 Stimmen

@information_interchange Wenn Sie explizit den Wahrheitsgehalt eines Wertes überprüfen wollen, verwenden Sie bool() . bool([]) == False wird bewertet zu True wie erwartet.

1 Stimmen

@information_interchange Das ist es wirklich nicht. Bedenken Sie, dass wenn [] == False bewertet nach True dann sollte aus Gründen der Konsistenz auch 0 == False y '' == False oder sogar '' == [] . Beachten Sie, dass es einen Unterschied zwischen Wahrheitsgehalt in einem booleschen Kontext und dem Testen von Gleichheit gibt. IMHO Clojure tut dies richtig: nur False und nil sind falsy. Pythons Regeln sind vernünftig. PHP hatte mal böse Regeln (habe ich schon lange nicht mehr benutzt, weiß es nicht mehr).

122voto

abarnert Punkte 332066

Patricks (akzeptierte) Antwort ist richtig: if not a: ist der richtige Weg, dies zu tun. Harley Holcombe's Antwort ist richtig, dass dies im PEP 8 Style Guide steht. Aber keine der Antworten erklärt, warum es eine gute Idee ist, das Idiom zu befolgen - selbst wenn Sie persönlich finden, dass es nicht explizit genug ist oder Ruby-Benutzer verwirrt oder was auch immer.

Python-Code und die Python-Gemeinschaft haben sehr starke Idiome. Wenn Sie sich an diese Idiome halten, ist Ihr Code für jeden, der sich mit Python auskennt, leichter zu lesen. Und wenn Sie gegen diese Idiome verstoßen, ist das ein starkes Signal.

Es stimmt, dass if not a: unterscheidet nicht zwischen leeren Listen und None oder numerisch 0, oder leere Tupel, oder leere benutzererstellte Auflistungstypen, oder leere benutzererstellte Nicht-ganz-Sammlungstypen, oder NumPy-Arrays mit einem Element, die als Skalare mit falschen Werten fungieren, usw. Und manchmal ist es wichtig, das explizit zu machen. Und in diesem Fall, wissen Sie qué die Sie explizit angeben möchten, so dass Sie genau darauf testen können. Zum Beispiel, if not a and a is not None: bedeutet "alles Falsche außer Keinem", während if len(a) != 0: bedeutet "nur leere Sequenzen - alles andere als eine Sequenz ist hier ein Fehler" usw. Damit testen Sie nicht nur genau das, was Sie testen wollen, sondern signalisieren dem Leser auch, dass dieser Test wichtig ist.

Aber wenn Sie nichts haben, worüber Sie explizit sprechen können, etwas anderes als if not a: ist eine Irreführung des Lesers. Sie signalisieren etwas als wichtig, obwohl es nicht wichtig ist. (Vielleicht machen Sie den Code auch weniger flexibel oder langsamer oder was auch immer, aber das ist alles weniger wichtig). Und wenn Sie Gewöhnlich den Leser so in die Irre zu führen, wenn Sie dann hacer Wenn Sie eine Unterscheidung treffen müssen, wird sie unbemerkt bleiben, weil Sie in Ihrem gesamten Code "Wolfsgeheul" gemacht haben.

3 Stimmen

"Und wenn man gegen diese Idiome verstößt, ist das ein deutliches Zeichen." Es kann ein starkes Signal sein, dass Sie einfach mit Code arbeiten, der von jemandem geschrieben wurde, der neu in Python ist, was viele Leute sind

107voto

MrWonderful Punkte 2402

Warum überhaupt prüfen?

Niemand scheint sich mit der Infragestellung Ihrer brauchen um die Liste überhaupt erst einmal zu testen. Da Sie keinen zusätzlichen Kontext angegeben haben, kann ich mir vorstellen, dass Sie diese Prüfung vielleicht gar nicht benötigen, aber mit der Listenverarbeitung in Python nicht vertraut sind.

Ich würde behaupten, dass die am pythonischsten ist es, überhaupt nicht zu prüfen, sondern nur die Liste zu bearbeiten. Auf diese Weise wird es das Richtige tun, egal ob es leer oder voll ist.

a = []

for item in a:
    <do something with item>

<rest of code>

Dies hat den Vorteil, dass alle Inhalte von a , ohne jedoch eine spezifische Prüfung auf Leere zu verlangen. Wenn a leer ist, wird der abhängige Block nicht ausgeführt und der Interpreter springt zur nächsten Zeile.

Wenn Sie das Feld tatsächlich auf Leere prüfen müssen:

a = []

if !a:
    <react to empty list>

<rest of code>

ist ausreichend.

7 Stimmen

Die Sache ist die, dass die Überprüfung, ob die Liste leer ist, ziemlich wichtig ist, zumindest für mich. Hast du dir überlegt, ob es ein Skript in der Liste gibt. <rest of code> die möglicherweise das Ergebnis der for Schleife? Oder verwenden Sie direkt einige Werte in a ? Wenn das Skript so konzipiert ist, dass es mit streng kontrollierten Eingaben abläuft, könnte die Überprüfung in der Tat ein wenig unnötig sein. Aber in den meisten Fällen variiert die Eingabe, und eine Überprüfung ist in der Regel besser.

2 Stimmen

Bei allem Respekt, nein. Ich dachte, dass jemand, der nicht genug über Python weiß, um zu wissen, dass "if <list>:" die richtige Antwort ist, fragt, wie man eine leere Liste überprüft. Dann bemerkte ich eine Vielzahl von Antworten, die unterschiedliche Meinungen vertraten, aber keine schien auf die ursprüngliche Frage einzugehen. Das ist es, was ich mit meiner Antwort erreichen wollte - sie sollten die Notwendigkeit prüfen, bevor sie fortfahren. Ich glaube, das habe ich in meiner Antwort ausdrücklich angedeutet.

1 Stimmen

@AmarthGûl - Wie könnte man bekommen. die Ergebnisse aus der for-Schleife an das Skript in <Rest des Codes> weiterleiten, um sie zu verarbeiten? Vielleicht in einer Liste? Oder vielleicht in einem Diktat? Wenn ja, gilt die gleiche Logik. Ich verstehe nicht, wie variable Eingabe in einem vernünftig konzipierten Code, in dem die Verarbeitung einer leeren Liste eine schlechte Idee wäre, eine Wirkung haben könnte.

76voto

George V. Reilly Punkte 14862

len() ist eine O(1)-Operation für Python-Listen, -Strings, -Dicts und -Sets. Python merkt sich intern die Anzahl der Elemente in diesen Containern.

JavaScript hat einen ähnlichen Begriff von wahr/falsch .

53voto

dubiousjim Punkte 4604

Ich hatte geschrieben:

if isinstance(a, (list, some, other, types, i, accept)) and not a:
    do_stuff

Ich bin mir nicht sicher, ob das daran lag, dass die Leser die Strategie ablehnten oder die Antwort in der vorgelegten Form nicht hilfreich war. Ich tue so, als sei es Letzteres, denn - was auch immer als "pythonisch" gilt - dies ist die richtige Strategie. Es sei denn, Sie haben bereits ausgeschlossen oder sind bereit, Fälle zu behandeln, in denen a ist, zum Beispiel, False benötigen Sie einen Test, der restriktiver ist als nur if not a: . Sie könnten etwas wie dieses 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 obige Antwort von @Mike. Die dritte Zeile könnte auch ersetzt werden durch:

elif isinstance(a, (list, tuple)) and not a:

wenn Sie nur Instanzen bestimmter Typen (und deren Untertypen) akzeptieren wollen, oder mit:

elif isinstance(a, (list, tuple)) and not len(a):

Sie können auf die explizite Typüberprüfung verzichten, aber nur, wenn der umgebende Kontext bereits sicherstellt, dass a ein Wert des Typs ist, auf den Sie vorbereitet sind, oder wenn Sie sicher sind, dass Typen, auf die Sie nicht vorbereitet sind, zu Fehlern führen werden (z. B. ein TypeError wenn Sie anrufen len für einen Wert, der nicht definiert ist), die Sie bereit sind zu behandeln. Im Allgemeinen scheinen die "pythonischen" Konventionen in diese letzte Richtung zu gehen. Quetschen Sie es wie eine Ente und lassen Sie es einen DuckError auslösen, wenn es nicht weiß, wie man quakt. Sie müssen trotzdem denken Sie sollten sich allerdings Gedanken darüber machen, welche Annahmen Sie treffen und ob die Fälle, auf die Sie nicht vorbereitet sind, wirklich an den richtigen Stellen Fehler machen werden. Die Numpy-Arrays sind ein gutes Beispiel dafür, dass ein blindes Vertrauen in len oder die boolesche Typisierung bewirkt möglicherweise nicht genau das, was Sie erwarten.

3 Stimmen

Es ist ziemlich selten, dass Sie eine erschöpfende Liste von 6 Typen haben, die Sie akzeptieren wollen, und nicht flexibel für andere Typen sind. Wenn Sie so etwas brauchen, brauchen Sie wahrscheinlich ein ABC. In diesem Fall würde es wahrscheinlich eines der stdlib ABCs sein, wie collections.abc.Sized o collections.abc.Sequence aber es könnte auch eine sein, die Sie selbst schreiben und register(list) an. Wenn Sie tatsächlich Code haben, bei dem es wichtig ist, leer von falsch zu unterscheiden, und auch Listen und Tupel von anderen Sequenzen zu unterscheiden, dann ist das korrekt - aber ich glaube nicht, dass Sie solchen Code haben.

14 Stimmen

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 typisierte Sprache, und dieses Maß an defensiver Kodierung behindert dies aktiv. Die Idee hinter dem Typsystem von Python ist, dass die Dinge so lange funktionieren sollten, wie das übergebene Objekt so funktioniert, wie es benötigt wird. Durch explizite Typprüfungen zwingt man den Aufrufer, bestimmte Typen zu verwenden, was dem Wesen der Sprache zuwiderläuft. Gelegentlich sind solche Dinge zwar notwendig (z.B. dass Strings nicht als Sequenzen behandelt werden), aber solche Fälle sind selten und fast immer am besten als Blacklists.

1 Stimmen

Wenn Sie wirklich überprüfen wollen, ob der Wert genau [] und nicht etwas Falsches einer anderen Art, dann sicher if a == []: erforderlich ist, anstatt mit isinstance herumzupfuschen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X