Vandaag kwam ik de dict
-methode get
tegen die, gegeven een sleutel in het woordenboek, de bijbehorende waarde retourneert.
Waarvoor is deze functie nuttig? Als ik een waarde wil vinden die is gekoppeld aan een sleutel in een woordenboek, kan ik gewoon dict[key]
doen, en het geeft hetzelfde terug:
dictionary = {"Name": "Harry", "Age": 17}
dictionary["Name"]
dictionary.get("Name")
Antwoord 1, autoriteit 100%
Hiermee kunt u een standaardwaarde opgeven als de sleutel ontbreekt:
dictionary.get("bogus", default_value)
retourneert default_value
(wat je ook kiest), terwijl
dictionary["bogus"]
zou een KeyError
veroorzaken.
Indien weggelaten, is default_value
None
, zodat
dictionary.get("bogus") # <-- No default specified -- defaults to None
retourneert None
net als
dictionary.get("bogus", None)
zou.
Antwoord 2, autoriteit 15%
Wat is de
dict.get()
methode?
Zoals reeds vermeld bevat de get
methode een extra parameter die de ontbrekende waarde aangeeft. Uit de documentatie
get(key[, default])
Retourneer de waarde voor sleutel als sleutel in het woordenboek staat, anders standaard. Als standaard niet is opgegeven, wordt deze standaard ingesteld op Geen, zodat deze methode nooit een
KeyError
oplevert.
Een voorbeeld kan zijn
>>> 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
Zijn er ergens snelheidsverbeteringen?
Zoals vermeld hier,
Het lijkt erop dat alle drie de benaderingen nu vergelijkbare prestaties vertonen (binnen ongeveer 10% van elkaar), min of meer onafhankelijk van de eigenschappen van de woordenlijst.
Eerder was get
aanzienlijk langzamer, maar nu is de snelheid bijna vergelijkbaar, samen met het extra voordeel van het retourneren van de standaardwaarde. Maar om al onze vragen te wissen, kunnen we testen op een vrij grote lijst (merk op dat de test alleen het opzoeken van alle geldige sleutels omvat)
def getway(d):
for i in range(100):
s = d.get(i)
def lookup(d):
for i in range(100):
s = d[i]
Tim nu deze twee functies met behulp van 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
Zoals we kunnen zien is de lookup sneller dan de get, omdat er geen functie-lookup is. Dit is te zien via 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
Waar is het nuttig?
Het is handig wanneer u een standaardwaarde wilt opgeven wanneer u een woordenboek zoekt. Dit vermindert
if key in dic:
val = dic[key]
else:
val = def_val
Naar een enkele regel, val = dic.get(key,def_val)
Waar is het NIET nuttig?
Telkens wanneer u een KeyError
wilt retourneren waarin staat dat de specifieke sleutel niet beschikbaar is. Het retourneren van een standaardwaarde brengt ook het risico met zich mee dat een bepaalde standaardwaarde ook een sleutel kan zijn!
Is het mogelijk om een
get
like-functie indict['key']
te hebben?
Ja! We moeten de __missing__
implementeren in een dict-subklasse.
Een voorbeeldprogramma kan zijn
class MyDict(dict):
def __missing__(self, key):
return None
Een kleine demonstratie kan zijn
>>> my_d = MyDict({1:2,2:3})
>>> my_d[1]
2
>>> my_d[3]
>>> repr(my_d[3])
'None'
Antwoord 3, autoriteit 3%
get
heeft een tweede optionele waarde. Als de opgegeven sleutel niet in uw woordenboek voorkomt, wordt deze waarde geretourneerd.
dictionary = {"Name": "Harry", "Age": 17}
dictionary.get('Year', 'No available data')
>> 'No available data'
Als u de tweede parameter niet opgeeft, wordt None
geretourneerd.
Als u indexering gebruikt zoals in dictionary['Year']
, zullen niet-bestaande sleutels KeyError
verhogen.
Antwoord 4, autoriteit 2%
Ik zal een praktisch voorbeeld geven van het schrapen van webgegevens met python, vaak krijg je sleutels zonder waarden, in die gevallen krijg je fouten als je dictionary [‘key’] gebruikt, terwijl dictionary.get (‘key’, ‘return_otherwise’) heeft geen problemen.
Op dezelfde manier zou ik ”.join(list) gebruiken in plaats van list[0] als je een enkele waarde uit een lijst probeert te halen.
hoop dat het helpt.
[Bewerken] Hier is een praktisch voorbeeld:
Stel, u roept een API aan, die een JOSN-bestand retourneert dat u moet ontleden. De eerste JSON ziet er als volgt uit:
{"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"}}
De tweede JOSN is als volgt:
{"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"}}
Merk op dat de tweede JSON de sleutel “submitdate_ts” mist, wat vrij normaal is in elke gegevensstructuur.
Dus wanneer u probeert toegang te krijgen tot de waarde van die sleutel in een lus, kunt u deze dan als volgt aanroepen:
for item in API_call:
submitdate_ts = item["bids"]["submitdate_ts"]
Dat zou kunnen, maar dan krijg je een traceback-fout voor de tweede JSON-regel, omdat de sleutel gewoon niet bestaat.
De juiste manier om dit te coderen kan de volgende zijn:
for item in API_call:
submitdate_ts = item.get("bids", {'x': None}).get("submitdate_ts")
{‘x’: Geen} is er om te voorkomen dat het tweede niveau een fout krijgt. Natuurlijk kunt u meer fouttolerantie in de code inbouwen als u aan het scrapen bent. Zoals eerst een if-voorwaarde specificeren
Antwoord 5, autoriteit 2%
Het doel is dat je een standaardwaarde kunt geven als de sleutel niet wordt gevonden, wat erg handig is
dictionary.get("Name",'harry')
Antwoord 6
Een probleem om op te letten bij het gebruik van .get()
:
Als het woordenboek de sleutel bevat die wordt gebruikt in de aanroep van .get()
en de waarde ervan None
is, wordt de .get()
methode retourneert None
zelfs als er een standaardwaarde is opgegeven.
Bijvoorbeeld, het volgende retourneert None
, niet 'alt_value'
zoals verwacht mag worden:
d = {'key': None}
assert None is d.get('key', 'alt_value')
De tweede waarde van
.get()
wordt alleen geretourneerd als de opgegeven sleutel NIET in het woordenboek staat, niet als de geretourneerde waarde van die aanroep None
is.
Antwoord 7
Waarvoor is deze functie nuttig?
Een bepaald gebruik is tellen met een woordenboek. Laten we aannemen dat u het aantal keren dat elk element in een bepaalde lijst voorkomt, wilt tellen. De gebruikelijke manier om dit te doen is door een woordenboek te maken waarin sleutels elementen zijn en waarden het aantal keren dat ze voorkomen.
fruits = ['apple', 'banana', 'peach', 'apple', 'pear']
d = {}
for fruit in fruits:
if fruit not in d:
d[fruit] = 0
d[fruit] += 1
Met de .get()
methode kun je deze code compacter en duidelijker maken:
for fruit in fruits:
d[fruit] = d.get(fruit, 0) + 1
Antwoord 8
Waarom dict.get(key) in plaats van dict[key]?
0. Samenvatting
Vergeleken met dict[key]
biedt dict.get
een terugvalwaarde bij het zoeken naar een sleutel.
1. Definitie
get(key[, default]) 4. Ingebouwde typen — Python 3.6.4rc1-documentatie
Retourneer de waarde voor sleutel als sleutel in het woordenboek staat, anders standaard. Als standaard niet is opgegeven, wordt deze standaard ingesteld op Geen, zodat deze methode nooit een KeyError oplevert.
d = {"Name": "Harry", "Age": 17}
In [4]: d['gender']
KeyError: 'gender'
In [5]: d.get('gender', 'Not specified, please add it')
Out[5]: 'Not specified, please add it'
2. Probleem dat het oplost.
Als je geen default value
hebt, moet je omslachtige codes schrijven om een dergelijke uitzondering af te handelen.
def get_harry_info(key):
try:
return "{}".format(d[key])
except KeyError:
return 'Not specified, please add it'
In [9]: get_harry_info('Name')
Out[9]: 'Harry'
In [10]: get_harry_info('Gender')
Out[10]: 'Not specified, please add it'
Als handige oplossing introduceert dict.get
een optionele standaardwaarde die bovenstaande onwettige codes vermijdt.
3. Conclusie
dict.get
heeft een extra standaardwaarde-optie om met uitzonderingen om te gaan als de sleutel afwezig is in het woordenboek
Antwoord 9
Een verschil, dat een voordeel kan zijn, is dat als we op zoek zijn naar een sleutel die niet bestaat, we Geen krijgen, niet zoals wanneer we de haakjesnotatie gebruiken, in welk geval we een foutmelding krijgen:
print(dictionary.get("address")) # None
print(dictionary["address"]) # throws KeyError: 'address'
Het laatste dat cool is aan de get-methode, is dat deze een extra optioneel argument voor een standaardwaarde ontvangt, dat wil zeggen als we probeerden de scorewaarde van een student te krijgen, maar de student heeft geen scoresleutel we kunnen in plaats daarvan een 0 krijgen.
Dus in plaats van dit (of iets dergelijks) te doen:
score = None
try:
score = dictionary["score"]
except KeyError:
score = 0
We kunnen dit doen:
score = dictionary.get("score", 0)
# score = 0
Antwoord 10
Een andere use-case die ik niet genoemd zie, is het argument key
voor functies zoals sorted
, max
en min
. Met de get
-methode kunnen sleutels worden geretourneerd op basis van hun waarden.
>>> ages = {"Harry": 17, "Lucy": 16, "Charlie": 18}
>>> print(sorted(ages, key=ages.get))
['Lucy', 'Harry', 'Charlie']
>>> print(max(ages, key=ages.get))
Charlie
>>> print(min(ages, key=ages.get))
Lucy
Dankzij dit antwoordop een andere vraag voor het verstrekken van deze use-case!
Antwoord 11
Op basis van gebruik moet deze get
-methode worden gebruikt.
Voorbeeld1
In [14]: user_dict = {'type': False}
In [15]: user_dict.get('type', '')
Out[15]: False
In [16]: user_dict.get('type') or ''
Out[16]: ''
Voorbeeld2
In [17]: user_dict = {'type': "lead"}
In [18]: user_dict.get('type') or ''
Out[18]: 'lead'
In [19]: user_dict.get('type', '')
Out[19]: 'lead'