Ich wollte testen, ob ein Schlüssel in einem Wörterbuch vorhanden ist, bevor ich den Wert für den Schlüssel aktualisiere. Ich habe folgenden Code geschrieben:
if 'key1' in dict.keys():
print "blah"
else:
print "boo"
Ich denke, dies ist nicht der beste Weg, um diese Aufgabe zu erfüllen. Gibt es eine bessere Möglichkeit, einen Schlüssel im Wörterbuch zu testen?
python
dictionary
Mohan Gulati
quelle
quelle
dict.keys()
wird eine Liste mit Schlüsseln gemäß der Dokumentation docs.python.org/2/library/stdtypes.html#dict.keys erstellt. Ich wäre jedoch überrascht, wenn dieses Muster in einer ernsthaften Implementierung nicht für die Übersetzung optimiert wäre zuif 'key1' in dict:
.x in dict.keys()
für Schlüssel zu überprüfen. Und das geschah , weil die übliche Art und Weise zu iterieren Schlüssel in Javafor (Type k : dict.keySet())
, so dass diese Gewohnheitfor k in dict.keys()
zu fühlen sich natürlicher an alsfor k in dict
(was sollte in Bezug auf die Leistung noch in Ordnung sein?), aber dann wird das Überprüfen der Schlüsselif k in dict.keys()
auch, was ein Problem ist ...if k in dict_:
testet das Vorhandensein von k in den KEYS von dict_, sodass Sie es immer noch nicht benötigendict_.keys()
. (Dies hat mich gebissen, wie es mir vorliest, als würde es auf einen Wert in dikt testen . Aber es ist nicht so.)Antworten:
in
ist die beabsichtigte Methode, um die Existenz eines Schlüssels in a zu testendict
.Wenn Sie eine Standardeinstellung wünschen, können Sie immer Folgendes verwenden
dict.get()
:und wenn Sie immer einen Standardwert für einen Schlüssel sicherstellen möchten, können Sie diesen entweder
dict.setdefault()
wiederholt oderdefaultdict
über dascollections
Modul verwenden, wie folgt:Im Allgemeinen ist das
in
Schlüsselwort jedoch der beste Weg, dies zu tun.quelle
get
wenn ich den Gegenstand trotzdem aus dem Wörterbuch ziehen will. Es macht keinen Sinn bei der Verwendungin
und das Element aus dem Wörterbuch zu ziehen.in
ist dies der beste Weg.0
. Das habe ich auf die harteSie müssen keine Tasten anrufen:
Dies ist viel schneller, da das Hashing des Wörterbuchs verwendet wird, anstatt eine lineare Suche durchzuführen, wie dies beim Aufrufen von Schlüsseln der Fall wäre.
quelle
if key in d1
dauerte es0.17265701293945312
Sekunden. Berufungif key in d1.keys()
hat0.23871088027954102
- das ist die klassische Definition einer Mikro-Optimierung.0.07884883880615234
Sekunden sparen ist keine Leistungssteigerung.keys()
bietet das Nichtanrufen einen Rechenvorteil von 0,01 Sekunden. Bei ~ 500.000 Schlüsseln erhaltenkeys()
Sie einen Vorteil von 0,1 Sekunden, wenn Sie nicht anrufen . Für ~ 5.000.000 Schlüssel, nicht Aufrufkeys()
ist 0,4 Sekunden schneller, aber für 50.000.000 Schlüssel CALLINGkeys()
IS 3 Sekunden schneller!Sie können in einem Wörterbuch für das Vorhandensein eines Schlüssels testen, die mit in Stichworten:
Eine häufige Verwendung zum Überprüfen der Existenz eines Schlüssels in einem Wörterbuch vor dem Mutieren besteht darin, den Wert standardmäßig zu initialisieren (z. B. wenn Ihre Werte beispielsweise Listen sind und Sie sicherstellen möchten, dass eine leere Liste vorhanden ist, an die Sie anhängen können beim Einfügen des ersten Wertes für einen Schlüssel). In solchen Fällen ist der
collections.defaultdict()
Typ möglicherweise von Interesse.In älterem Code finden Sie möglicherweise auch einige Verwendungen
has_key()
einer veralteten Methode zum Überprüfen der Existenz von Schlüsseln in Wörterbüchern (verwenden Siekey_name in dict_name
stattdessen einfach ).quelle
key in dict.keys()
. Versuchen Sie, den gesamten Code mit Ausnahme dieser Überprüfung zu entfernen, und sehen Sie, was Ihr Ergebnis ist.Sie können dies verkürzen:
Dies ist jedoch bestenfalls eine kosmetische Verbesserung. Warum glaubst du, ist das nicht der beste Weg?
quelle
Weitere Informationen zur Geschwindigkeitsausführung der vorgeschlagenen Methoden der akzeptierten Antwort (10-m-Schleifen):
'key' in mydict
verstrichene Zeit 1,07 Sekmydict.get('key')
verstrichene Zeit 1,84 Sekmydefaultdict['key']
verstrichene Zeit 1,07 SekVerwenden Sie daher
in
oderdefaultdict
werden dagegen empfohlenget
.quelle
get
voll und ganz zu, dass 's 1.84s <1.07 * 2 ;-PIch würde empfehlen, stattdessen die
setdefault
Methode zu verwenden. Es klingt so, als würde es alles tun, was Sie wollen.quelle
setdefault
mit der Frage des OP zu tun?Das Wörterbuch in Python verfügt über eine get-Methode ('key', Standard). Sie können also einfach einen Standardwert festlegen, falls kein Schlüssel vorhanden ist.
quelle
Was ist mit der Verwendung von EAFP (leichter um Vergebung als um Erlaubnis zu bitten):
Siehe andere SO-Beiträge:
Verwenden Sie try vs if in Python oder
Überprüfen der Existenz von Mitgliedern in Python
quelle
Verwenden des ternären Operators:
quelle
Die Möglichkeiten, wie Sie die Ergebnisse erhalten können, sind:
Was besser ist, hängt von drei Dingen ab:
Lesen Sie mehr: http://paltman.com/try-except-performance-in-python-a-simple-test/
Verwendung von try / block anstelle von 'in' oder 'if':
quelle
2to3
und festgestellt, dass die Syntax ohne Versuch immer schneller ist als die Syntax mit Versuch, selbst wenn sich der Schlüssel im Diktat befindet.Nur Python 2: (und Python 2.7 unterstützt
in
bereits)Sie können die Methode has_key () verwenden:
quelle
.has_key()
wurde veraltet ; Sie solltenin
wie in anderen Antworten gezeigt verwenden.Nur eine Info zu Chris. B (beste Antwort):
Funktioniert auch; Der Grund dafür ist, dass der Aufruf
int()
zurückgibt0
, wasdefaultdict
hinter den Kulissen (beim Erstellen eines Wörterbuchs) geschieht, daher der Name "Factory Function" in der Dokumentation.quelle
defaultdict(lambda: 0)
statt verwendet,defaultdict(int)
weil ich denke, es ist klarer, was los ist; Der Leser muss nicht wissen, dass Sie erhalten,0
wenn Sieint()
ohne Argumente anrufen . YMMV.Um die Idee zu bekommen, wie das geht, überprüfen wir zuerst, welche Methoden wir im Wörterbuch aufrufen können. Hier sind die Methoden:
Die brutale Methode, um zu überprüfen, ob der Schlüssel bereits vorhanden ist, kann die folgende sein
get()
:Die anderen beiden interessanten Methoden
items()
undkeys()
klingt nach zu viel Arbeit. Lassen Sie uns also untersuchen, ob diesget()
die richtige Methode für uns ist. Wir haben unser Diktatd
:Der Druck zeigt, dass der Schlüssel, den wir nicht haben, zurückgegeben wird
None
:Wir
können dasverwenden, um die Informationen zu erhalten, ob der Schlüssel vorhanden ist oder nicht. Aber bedenken Sie dies, wenn wir ein Diktat mit einem einzigen erstellenkey:None
:Das Führen dieser
get()
Methode ist nicht zuverlässig, falls einige Werte vorliegenNone
. Diese Geschichte sollte ein glücklicheres Ende haben. Wenn wir denin
Komparator verwenden:Wir bekommen die richtigen Ergebnisse. Wir können den Python-Bytecode untersuchen:
Dies zeigt, dass
in
Vergleichsoperator nicht nur zuverlässiger, sondern sogar schneller ist alsget()
.quelle
.get()
kann ein zweites Argument für dendefault
Wert haben, das verwendet werden kann, um das Problem zu behandeln, wokey:None
. Beispiel:d.get("key", False)
.get()
ist der schnellste Weg. Eine andere Option ist die Zuweisung in einemtry
/except
BlockPython-Wörterbuch hat die Methode aufgerufen
__contains__
. Diese Methode gibt True zurück, wenn das Wörterbuch den Schlüssel hat. Andernfalls wird False zurückgegeben.quelle
__contains__
direkt anzurufen . Die richtige Vorgehensweise besteht darin, denin
Operator zu verwenden , dercontainment check
die__contains__
Funktion aufruft .foo = x['foo'] if x.__contains__('foo') else 'bar'
. Irgendwelche Ideen, wie derin
Operator als Teil dieses Ausdrucks verwendet werden könnte?foo = x['foo'] if 'foo' in x else 'bar'
Teilen Sie eine weitere Möglichkeit, mit booleschen Operatoren zu überprüfen, ob ein Schlüssel vorhanden ist.
Dies kehrt zurück
Erläuterung
Zunächst sollten Sie wissen , dass in Python,
0
,None
oder Objekte mit der Länge Null bewerten zuFalse
. Alles andere wird ausgewertetTrue
. Boolesche Operationen werden von links nach rechts ausgewertet und geben den Operanden nicht True oder False zurück.Sehen wir uns ein Beispiel an:
Da
'Some string'
ausgewertet wird,True
wird der Rest vonor
nicht ausgewertet und es wird keine Division durch Nullfehler ausgelöst.Wenn wir jedoch wechseln, wird die Reihenfolge
1/0
zuerst ausgewertet und eine Ausnahme ausgelöst:Wir können dieses Muster verwenden, um zu überprüfen, ob ein Schlüssel vorhanden ist.
macht das gleiche wie
Dies gibt bereits das richtige Ergebnis zurück, wenn der Schlüssel vorhanden ist, aber wir möchten, dass er 'boo' druckt, wenn dies nicht der Fall ist. Also nehmen wir das Ergebnis und
or
es mit'boo'
quelle
Sie können die
for
Schleife verwenden, um das Wörterbuch zu durchlaufen und den Namen des Schlüssels abzurufen, den Sie im Wörterbuch finden möchten. Überprüfen Sie anschließend, ob er vorhanden ist oder nicht: Verwenden Sie dieif
Bedingung:quelle
it is exist
undnot exist