web-dev-qa-db-fra.com

Pourquoi dict.get (key) au lieu de dict [key]?

Aujourd'hui, je suis tombé sur la méthode dictget 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")
443
stensootla

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. 

735
unutbu

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é dans dict['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'
93
Bhargav Rao

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.

26
FallenAngel

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

18
kevin

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')
14
hackartist

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
2
jetpack_guy
  • 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]
0
U9-Forward

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.

0
Colton Hicks

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'
0
Muthuvel

Pourquoi dict.get (key) au lieu de dict [key]?

0. Résumé

Comparé à dict[key], dict.get fournit une valeur de repli lors de la recherche d'une clé.

1. Définition

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'

2. Problème résolu.

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.

3. Conclusion

dict.get a une option de valeur par défaut supplémentaire pour traiter une exception si la clé est absente du dictionnaire

0
JawSaw