Aujourd'hui, je suis tombé sur la méthode dict
get
qui, à partir d'une clé du dictionnaire, renvoie la valeur associée.
Dans quel but cette fonction est-elle utile? Si je voulais trouver une valeur associée à une clé dans un dictionnaire, je peux simplement faire dict[key]
, et cela retourne la même chose:
dictionary = {"Name": "Harry", "Age": 17}
dictionary["Name"]
dictionary.get("Name")
Il vous permet de fournir une valeur par défaut si la clé est manquante:
dictionary.get("bogus", default_value)
renvoie default_value
(quel que soit votre choix), alors que
dictionary["bogus"]
soulèverait une KeyError
.
Si omis, default_value
est None
, tel que
dictionary.get("bogus") # <-- No default specified -- defaults to None
renvoie None
comme
dictionary.get("bogus", None)
aurait.
Quelle est la méthode
dict.get()
?
Comme déjà mentionné, la méthode get
contient un paramètre supplémentaire qui indique la valeur manquante. De la documentation
get(key[, default])
Renvoie la valeur pour clé si clé est dans le dictionnaire, sinon par défaut. Si default n'est pas spécifié, la valeur par défaut est None, de sorte que cette méthode ne déclenche jamais une
KeyError
.
Un exemple peut être
>>> 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
Y a-t-il des améliorations de vitesse quelque part?
Comme mentionné ici ,
Il semble que les trois approches présentent maintenant des performances similaires (à environ 10% l'une de l'autre), plus ou moins indépendantes des propriétés de la liste de mots.
Auparavant, get
était considérablement plus lent. Cependant, maintenant, la vitesse est presque comparable, avec l'avantage supplémentaire de retourner la valeur par défaut. Mais pour effacer toutes nos requêtes, nous pouvons tester sur une liste assez longue (notez que le test inclut uniquement la recherche de toutes les clés valides)
def getway(d):
for i in range(100):
s = d.get(i)
def lookup(d):
for i in range(100):
s = d[i]
Maintenant, chronométrez ces deux fonctions en utilisant 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
Comme nous pouvons le constater, la recherche est plus rapide que l’obtenir car il n’ya pas de recherche de fonction. Ceci peut être vu à travers 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
Où cela sera-t-il utile?
Cela vous sera utile si vous souhaitez fournir une valeur par défaut lorsque vous recherchez un dictionnaire. Cela réduit
if key in dic:
val = key[dic]
else:
val = def_val
Sur une seule ligne, val = dic.get(key,def_val)
Où cela ne sera-t-il PAS utile?
Chaque fois que vous souhaitez renvoyer une KeyError
indiquant que la clé en question n'est pas disponible. Le renvoi d'une valeur par défaut comporte également le risque qu'une valeur par défaut particulière soit également une clé!
Est-il possible d'avoir
get
comme fonctionnalité dansdict['key']
?
Oui! Nous devons implémenter le __missing__
dans une sous-classe dict.
Un exemple de programme peut être
class MyDict(dict):
def __missing__(self, key):
return None
Une petite démonstration peut être
>>> my_d = MyDict({1:2,2:3})
>>> my_d[1]
2
>>> my_d[3]
>>> repr(my_d[3])
'None'
get
prend une deuxième valeur facultative. Si la clé spécifiée n'existe pas dans votre dictionnaire, cette valeur sera renvoyée.
dictionary = {"Name": "Harry", "Age": 17}
dictionary.get('Year', 'No available data')
>> 'No available data'
Si vous ne spécifiez pas le deuxième paramètre, None
sera renvoyé.
Si vous utilisez l'indexation comme dans dictionary['Year']
, des clés non existantes augmenteront KeyError
.
Je donnerai un exemple pratique de grattage de données Web avec Python. Souvent, vous obtiendrez des clés sans valeur. Dans ce cas, vous obtiendrez des erreurs si vous utilisez dictionnaire ['clé'], ',' return_otherwise ') n'a pas de problèmes.
De même, j'utiliserais '' .join (list) par opposition à list [0] si vous essayez de capturer une valeur unique à partir d'une liste.
j'espère que ça aide.
[Modifier] Voici un exemple pratique:
Disons que vous appelez une API qui renvoie un fichier JOSN que vous devez analyser. Le premier JSON se présente comme suit:
{"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"}}
Le deuxième JOSN est comme ça:
{"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"}}
Notez que le second JSON manque de la clé "submitdate_ts", ce qui est plutôt normal dans toute structure de données.
Ainsi, lorsque vous essayez d'accéder à la valeur de cette clé dans une boucle, pouvez-vous l'appeler comme suit:
for item in API_call:
submitdate_ts = item["bids"]["submitdate_ts"]
Vous pourriez le faire, mais vous obtiendrez une erreur de trace pour la deuxième ligne JSON, car la clé n'existe tout simplement pas.
La manière appropriée de coder ceci pourrait être la suivante:
for item in API_call:
submitdate_ts = item.get("bids", {'x': None}).get("submitdate_ts")
{'x': None} est là pour éviter une erreur au second niveau. Bien entendu, vous pouvez intégrer davantage de tolérance aux pannes dans le code si vous effectuez un nettoyage. Comme en spécifiant d'abord une condition if
Le but est que vous puissiez donner une valeur par défaut si la clé n'est pas trouvée, ce qui est très utile
dictionary.get("Name",'harry')
Dans quel but cette fonction est-elle utile?
Une utilisation particulière compte avec dictionnaire. Supposons que vous souhaitiez compter un nombre d'occurrences de chaque élément dans une liste donnée. Pour ce faire, il est courant de créer un dictionnaire où les clés sont des éléments et les valeurs, le nombre d'occurrences.
fruits = ['Apple', 'banana', 'Peach', 'Apple', 'pear']
d = {}
for fruit in fruits:
if fruit not in d:
d[fruit] = 0
d[fruit] += 1
En utilisant la méthode .get (), vous pouvez rendre ce code plus compact et plus clair:
for fruit in fruits:
d[fruit] = d.get(fruit, 0) + 1
dict.get
ne retournera rien par défaut si la clé n'existe pas, mais si vous en mettez un deuxième argument, il le retournera si la clé n'existe pas.
OTOH dict[key]
lèvera KeyError
si la clé n'existe pas.
Voici un exemple (lire les commentaires):
>>> d={'a':[1,2,3],'b':[4,5,6]} # Create a dictionary
>>> d['c'] # Hoops, error key does not exist
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
d['c']
KeyError: 'c'
>>> d.get('c') # no error because of `get`, so nothing returned
>>> print(d.get('c')) # i print it, oh `None` is the output
None
>>> d.get('c',100) # Okay now i set second argument's value to `100`, hoopa output is `100`
100
>>> d['a'] # Works, key exist
[1, 2, 3]
>>> d.get('a') # work too, key exist
[1, 2, 3]
Il faut être conscient de l'utilisation de .get ():
Si le dictionnaire contient la clé utilisée dans l'appel à .get()
et que sa valeur est None
, .get()
renvoie None
même si une deuxième valeur est fournie.
Par exemple, ce qui suit retourne None
, et non pas 'alt_value' comme on pouvait s'y attendre:
d = {'key': None}
d.get('key', 'alt_value')
La deuxième valeur de .get()
n'est renvoyée que si la clé fournie N'EST PAS dans le dictionnaire, pas si la valeur renvoyée par cet appel est None
.
Basé sur l'utilisation devrait utiliser cette méthode get
.
Exemple 1
In [14]: user_dict = {'type': False}
In [15]: user_dict.get('type', '')
Out[15]: False
In [16]: user_dict.get('type') or ''
Out[16]: ''
Exemple2
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'
Pourquoi dict.get (key) au lieu de dict [key]?
Comparé à dict[key]
, dict.get
fournit une valeur de repli lors de la recherche d'une clé.
get (key [ default]) 4. Types intégrés - Documentation Python 3.6.4rc1
Renvoie la valeur pour clé si clé est dans le dictionnaire, sinon par défaut. Si default n'est pas spécifié, la valeur par défaut est None, de sorte que cette méthode ne déclenche jamais d'erreur KeyError.
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'
Si vous n'avez pas default value
, vous devez écrire des codes encombrants pour gérer une telle exception.
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'
Comme solution pratique, dict.get
introduit une valeur par défaut facultative évitant les codes inopinés ci-dessus.
dict.get
a une option de valeur par défaut supplémentaire pour traiter une exception si la clé est absente du dictionnaire