wake-up-neo.net

Die Pythonic-Methode, um zu überprüfen, ob ein Wert in einem Wörterbuch definiert ist/eine Länge von Null hat

Angenommen, ich habe ein Wörterbuch und möchte prüfen, ob einem Schlüssel ein nicht leerer Wert zugeordnet ist. Eine Möglichkeit, dies zu tun, wäre die len-Funktion:

mydict = {"key" : "value", "emptykey" : ""}
print "True" if len(mydict["key"]) > 0 else "False"  # prints true
print "True" if len(mydict["emptykey"]) > 0 else "False"  # prints false

Man kann sich jedoch auf die Semantik von Python verlassen und wie ein Objekt definiert wird, das es als true auswertet und den len-Aufruf weglässt:

mydict = {"key" : "value", "emptykey" : ""}
print "True" if mydict["key"] else "False"  # prints true
print "True" if mydict["emptykey"] else "False"  # prints false

Ich bin mir jedoch nicht sicher, was mehr Pythonic ist. Das erste fühlt sich "explizit ist besser als implizit" an, das zweite fühlt sich jedoch "einfach ist besser als komplex" an.

Ich frage mich auch, ob das Auslassen des len-Aufrufs mich beißen könnte, da das Diktat, mit dem ich arbeite, nicht notwendigerweise Strings enthält, sondern andere lesbare Typen (Listen, Mengen usw.) enthalten kann. OTOH, in dem ersten (mit dem len-Aufruf), wenn None als Wert gespeichert wird, wird der Code explodieren, wohingegen die Nicht-len-Version wie erwartet funktioniert (wird zu false).

Welche Version ist sicherer und mehr Pythonic?

Edit: Klarstellung der Annahmen: Ich Wissen Der Schlüssel befindet sich im Wörterbuch, und ich weiß, dass Werte lesbar sind. Ich kann auch nicht vermeiden, dass Werte mit der Länge Null in das Wörterbuch aufgenommen werden.

Edit # 2: Es scheint, als würden die Leute den Punkt meiner Frage verfehlen. Ich versuche nicht zu ermitteln, auf welche Weise Pythonic am sichersten ist, um zu überprüfen, ob ein Schlüssel in einem Wörterbuch vorhanden ist. Ich versuche zu prüfen, ob ein Wert die Länge Null hat oder nicht

19
Adam Parkin

Wenn Sie wissen, dass sich der Schlüssel im Wörterbuch befindet, verwenden Sie

if mydict["key"]:
    ...

Es ist einfach, leicht zu lesen und sagt: "Wenn der an key gebundene Wert mit True ausgewertet wird, tun Sie etwas". Das wichtige Leckerbissen ist, dass Containertypen (dict, list, Tuple, str usw.) nur in True ausgewertet werden, wenn ihre len größer als 0 ist.

Es wird auch eine KeyError ausgelöst, wenn Ihre Voraussetzung, dass ein Schlüssel in mydict ist, verletzt wird.

All dies macht es Pythonic.

21
Ethan Furman
print (bool(mydict.get('key')))

oder in einer if-Anweisung:

print ('True' if mydict.get('key') else 'False')

Wenn der Wert, der nicht vorhanden ist, ein Fehler ist (d. H. Sie erwarten, dass er vorhanden ist), sollten Sie Lösung 2 wählen, d. H.

print ('True' if mydict['key'] else 'False')

Dadurch kann mydict['key'] die effizienteste Definition für das Leeren auswählen. Bei einigen Objekten (z. B. Objekten in Clustern) ist das Bestimmen der tatsächlichen Länge eine ziemlich komplizierte Operation, während Sie einfach feststellen können, ob das Objekt leer ist oder nicht.

Sie könnten auch mit '', d. H. mydict['key'] == '', vergleichen, um Ihren Ausdruck deutlich zu machen. Die Verwendung von len funktioniert, ist aber nicht so intuitiv.

Zusammenfassend lassen sich dem getesteten Objekt überlassen, um zu definieren, ob es leer ist oder nicht und es einfach in bool umzuwandeln.

13
phihag

Ich würde eine Variante der ersten Option verwenden:

>>> mydict = {"key" : "value", "emptykey" : ""}
>>> print bool(mydict["key"])
True
>>> print bool(mydict["emptykey"])
False

Jede Klasse, die __len__ bereitstellt, kann direkt in einen booleschen Code konvertiert werden (siehe Truth Value Testing ). bool(container) entspricht bool(len(container)). Eine Länge von 0 wird zum booleschen Falsename__, während alle anderen Längen Truesind. Sie werden niemals ein Objekt mit negativer Länge haben. Außerdem können die Booleschen Variablen Trueund Falsedirekt über printgedruckt werden, sodass Sie die Bedingung nicht benötigen.

3
Nathan

Von hier :

Im Zusammenhang mit booleschen Operationen und auch wenn Ausdrücke von Steuerflussanweisungen verwendet werden, werden die folgenden Werte als falsch interpretiert: False, None, numerische Null aller Typen sowie leere Zeichenfolgen und Container (einschließlich Zeichenfolgen, Tupeln, Listen, Wörterbüchern) , sets und frozensets). Alle anderen Werte werden als wahr interpretiert.

Ich denke, es ist sicher zu sagen, dass eine direkte Auswertung die beste Option ist - obwohl, wie @phihag gesagt hat, die Verwendung von get sicherer ist, da Sie vor einer KeyError geschützt werden.

3
Nate

Der Titel und der erste Satz drücken zwei leicht unterschiedliche Fragen aus.

Für die Titelfrage 

Die Pythonic-Methode zum Überprüfen, ob ein Wert in einem Wörterbuch definiert ist

Ich würde mitgehen 

"key" in mydict

und für die zweite Frage

Angenommen, ich habe ein Wörterbuch und möchte prüfen, ob einem Schlüssel ein nicht leerer Wert zugeordnet ist.

Ich würde mitgehen 

"key" in mydict and bool(mydict["key"])

Der erste Teil prüft, ob "Schlüssel" in "mydict" vorhanden ist, und der zweite Teil gibt "true" für alle Werte von "Schlüssel" außer "Falsch", "Keine", den leeren String, das leere Wörterbuch, die leere Liste und "0" zurück.

1
oivvio

Die pythonischste Methode wäre, den undefinierten Wert nicht zu definieren (ob dies verwendbar ist, hängt jedoch davon ab, wofür Sie es verwenden) und verwendet in:

mydict = {"key" : "value"}
print "True" if "key" in mydict else "False"  # prints true
print "True" if "emptykey" in mydict else "False"  # prints false

Ansonsten haben Sie drei Möglichkeiten:

  1. Verwenden Sie mydict.get. Sie sollten dies verwenden, wenn sich der Schlüssel im Wörterbuch befindet oder nicht.
  2. Verwenden Sie mydict[key]. Sie sollten dies verwenden, wenn Sie sicher sind, dass der gewünschte Schlüssel im Diktat enthalten ist.
  3. Verwenden Sie len(mydict[key]) > 0. Dies funktioniert nur, wenn für den Wert __len__ definiert wurde. Normalerweise hängt der Wahrheitswert eines Containerwerts sowieso von dem __len__ ab, daher sind die obigen Angaben vorzuziehen.
0
Robin

Sie können einfach überprüfen, ob ein Wert im Diktat eine Länge von Null hat oder nicht, indem Sie:

# To get keys which having zero length value:
keys_list = [key for key,val in mydict.items() if not val]


# To check whether the dict has any zero length value in it (returns True or False):
any_empty_vals = bool(len(['' for x in data_dict.values() if not x]))
0
Safvan CK

Von Ihren beiden Beispielen ziehe ich das zweite vor.

Ich empfehle jedoch, die leeren Schlüssel nicht zu speichern. Auch ein Defaultdict würde hier gut funktionieren:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d[1].append(1)
>>> 1 in d
True

Wenn Sie leere Schlüssel speichern müssen, benötigen Sie die Zeichenfolgenwerte "True" und "False" nicht. Mach einfach das:

print bool(mydict[key])
0