1134 Stimmen

Warum dict.get(Schlüssel) anstelle von dict[Schlüssel]?

Heute bin ich auf die dict Methode get die bei Angabe eines Schlüssels im Wörterbuch den zugehörigen Wert zurückgibt.

Für welchen Zweck ist diese Funktion nützlich? Wenn ich einen Wert finden möchte, der einem Schlüssel in einem Wörterbuch zugeordnet ist, kann ich einfach Folgendes tun dict[key] und erhält dasselbe Ergebnis:

dictionary = {"Name": "Harry", "Age": 17}
dictionary["Name"]
dictionary.get("Name")

1651voto

unutbu Punkte 769083

Sie ermöglicht es Ihnen, einen Standardwert anzugeben, wenn der Schlüssel fehlt:

dictionary.get("bogus", default_value)

gibt zurück. default_value (wie auch immer Sie es wählen), während

dictionary["bogus"]

würde eine KeyError .

Falls ausgelassen, default_value es None , so dass

dictionary.get("bogus")  # <-- No default specified -- defaults to None

gibt zurück. None genau wie

dictionary.get("bogus", None)

würde.

238voto

Bhargav Rao Punkte 45981

Was ist die dict.get() Methode?

Wie bereits erwähnt, ist die get Methode enthält einen zusätzlichen Parameter, der den fehlenden Wert angibt. Aus der Dokumentation

get(key[, default])

Rückgabe des Wertes für key, wenn key im Wörterbuch enthalten ist, sonst Standard. Wenn default nicht angegeben wird, ist es standardmäßig None, so dass diese Methode nie einen Fehler auslöst. KeyError .

Ein Beispiel kann sein

>>> d = {1:2,2:3}
>>> d[1]
2
>>> d.get(1)
2
>>> d.get(3)
>>> repr(d.get(3))
'None'
>>> d.get(3,1)
1

Gibt es irgendwo Verbesserungen bei der Geschwindigkeit?

Wie erwähnt ici ,

Es scheint, dass alle drei Ansätze nun eine ähnliche Leistung aufweisen (innerhalb von etwa 10 % voneinander), mehr oder weniger unabhängig von den Eigenschaften der Wortliste.

Frühere get war erheblich langsamer. Jetzt ist die Geschwindigkeit jedoch fast vergleichbar, mit dem zusätzlichen Vorteil, dass der Standardwert zurückgegeben wird. Um alle unsere Abfragen zu klären, können wir einen Test mit einer ziemlich großen Liste durchführen (beachten Sie, dass der Test nur die Suche nach allen gültigen Schlüsseln umfasst)

def getway(d):
    for i in range(100):
        s = d.get(i)

def lookup(d):
    for i in range(100):
        s = d[i]

Nun werden diese beiden Funktionen mit timeit

>>> import timeit
>>> print(timeit.timeit("getway({i:i for i in range(100)})","from __main__ import getway"))
20.2124660015
>>> print(timeit.timeit("lookup({i:i for i in range(100)})","from __main__ import lookup"))
16.16223979

Wie wir sehen können, ist der Lookup schneller als der Get, da es keinen Funktions-Lookup gibt. Dies ist zu erkennen durch dis

>>> def lookup(d,val):
...     return d[val]
... 
>>> def getway(d,val):
...     return d.get(val)
... 
>>> dis.dis(getway)
  2           0 LOAD_FAST                0 (d)
              3 LOAD_ATTR                0 (get)
              6 LOAD_FAST                1 (val)
              9 CALL_FUNCTION            1
             12 RETURN_VALUE        
>>> dis.dis(lookup)
  2           0 LOAD_FAST                0 (d)
              3 LOAD_FAST                1 (val)
              6 BINARY_SUBSCR       
              7 RETURN_VALUE  

Wo wird sie nützlich sein?

Sie ist immer dann nützlich, wenn Sie einen Standardwert angeben wollen, wenn Sie in einem Wörterbuch nachschlagen. Dies reduziert

 if key in dic:
      val = dic[key]
 else:
      val = def_val

Zu einer einzigen Zeile, val = dic.get(key,def_val)

Wo wird sie NICHT nützlich sein?

Wann immer Sie eine KeyError die besagt, dass der betreffende Schlüssel nicht verfügbar ist. Die Rückgabe eines Standardwerts birgt auch das Risiko, dass ein bestimmter Standardwert auch ein Schlüssel sein kann!

Ist es möglich, eine get wie die Funktion in dict['key'] ?

Ja! Wir müssen die __missing__ in einer dict-Unterklasse.

Ein Beispielprogramm kann sein

class MyDict(dict):
    def __missing__(self, key):
        return None

Eine kleine Demonstration kann sein

>>> my_d = MyDict({1:2,2:3})
>>> my_d[1]
2
>>> my_d[3]
>>> repr(my_d[3])
'None'

38voto

FallenAngel Punkte 17178

get nimmt einen zweiten optionalen Wert an. Wenn der angegebene Schlüssel in Ihrem Wörterbuch nicht vorhanden ist, wird dieser Wert zurückgegeben.

dictionary = {"Name": "Harry", "Age": 17}
dictionary.get('Year', 'No available data')
>> 'No available data'

Wenn Sie den zweiten Parameter nicht angeben, None zurückgegeben werden.

Wenn Sie die Indizierung wie in dictionary['Year'] werden nicht existierende Schlüssel zu KeyError .

31voto

user1847 Punkte 2842

Ein Problem, das bei der Verwendung von .get() :

Wenn das Wörterbuch den Schlüssel enthält, der im Aufruf von .get() und sein Wert ist None El .get() Methode wird zurückgegeben None auch wenn ein Standardwert angegeben wird.

Zum Beispiel wird Folgendes zurückgegeben None no 'alt_value' wie zu erwarten ist:

d = {'key': None}
assert None is d.get('key', 'alt_value')

.get() wird nur dann zurückgegeben, wenn der übergebene Schlüssel NICHT im Wörterbuch enthalten ist, und nicht, wenn der Rückgabewert des Aufrufs None .

26voto

kevin Punkte 1037

Ich werde ein praktisches Beispiel in Scraping Web-Daten mit Python, eine Menge der Zeit, die Sie erhalten Schlüssel mit keine Werte, in diesen Fällen erhalten Sie Fehler, wenn Sie verwenden dictionary['key'], während dictionary.get('key', 'return_otherwise') hat keine Probleme.

In ähnlicher Weise würde ich ''.join(list) anstelle von list[0] verwenden, wenn Sie versuchen, einen einzelnen Wert aus einer Liste zu erfassen.

Ich hoffe, es hilft.

[Bearbeiten] Hier ist ein praktisches Beispiel:

Nehmen wir an, Sie rufen eine API auf, die eine JOSN-Datei zurückgibt, die Sie parsen müssen. Die erste JSON-Datei sieht wie folgt aus:

{"bids":{"id":16210506,"submitdate":"2011-10-16 15:53:25","submitdate_f":"10\/16\/2011 at 21:53 CEST","submitdate_f2":"p\u0159ed 2 lety","submitdate_ts":1318794805,"users_id":"2674360","project_id":"1250499"}}

Das zweite JOSN sieht so aus:

{"bids":{"id":16210506,"submitdate":"2011-10-16 15:53:25","submitdate_f":"10\/16\/2011 at 21:53 CEST","submitdate_f2":"p\u0159ed 2 lety","users_id":"2674360","project_id":"1250499"}}

Beachten Sie, dass im zweiten JSON der Schlüssel "submitdate_ts" fehlt, was in jeder Datenstruktur ziemlich normal ist.

Wenn Sie also versuchen, in einer Schleife auf den Wert dieses Schlüssels zuzugreifen, können Sie ihn mit dem folgenden aufrufen:

for item in API_call:
    submitdate_ts = item["bids"]["submitdate_ts"]

Sie könnten, aber es wird Ihnen einen Traceback-Fehler für die zweite JSON-Zeile, weil der Schlüssel einfach nicht existiert.

Eine geeignete Kodierung könnte folgendermaßen aussehen:

for item in API_call:
    submitdate_ts = item.get("bids", {'x': None}).get("submitdate_ts")

{'x': None} ist dazu da, um zu verhindern, dass die zweite Ebene einen Fehler erhält. Natürlich können Sie mehr Fehlertoleranz in den Code einbauen, wenn Sie Scraping betreiben. Zum Beispiel, indem man zuerst eine if-Bedingung angibt

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