2680 votes

Vérifier si une clé donnée existe déjà dans un dictionnaire

Je voulais tester si une clé existe dans un dictionnaire avant de mettre à jour la valeur de cette clé. J'ai écrit le code suivant :

if 'key1' in dict.keys():
  print "blah"
else:
  print "boo"

Je pense que ce n'est pas la meilleure façon d'accomplir cette tâche. Existe-t-il un meilleur moyen de tester la présence d'une clé dans le dictionnaire ?

31 votes

Appel à dict.keys() crée une liste de clés, selon la documentation docs.python.org/2/library/stdtypes.html#dict.keys mais je serais surpris si ce modèle n'était pas optimisé pour, dans une implémentation sérieuse, se traduire par if 'key1' in dict: .

7 votes

J'ai finalement découvert pourquoi beaucoup de mes scripts Python étaient si lents :) :(. C'est parce que j'ai utilisé x in dict.keys() pour vérifier les clés. Et c'est arrivé parce que la façon habituelle d'itérer sur les clés en Java est for (Type k : dict.keySet()) cette habitude causant for k in dict.keys() pour se sentir plus naturel que for k in dict (ce qui devrait encore être correct en termes de performances ?), mais la vérification des clés devient alors if k in dict.keys() aussi, ce qui est un problème...

4 votes

@EvgeniSergeev if k in dict_: teste la présence de k dans les KEYS de dict_, donc vous n'avez toujours pas besoin de dict_.keys() . (Cela m'a fait tiquer, car j'ai l'impression qu'il s'agit d'un test pour une valeur en dictée. Mais ce n'est pas le cas).

4166voto

Chris B. Points 14211

in est le moyen prévu pour tester l'existence d'une clé dans un fichier dict .

d = dict()

for i in xrange(100):
    key = i % 10
    if key in d:
        d[key] += 1
    else:
        d[key] = 1

Si vous vouliez un défaut, vous pouvez toujours utiliser dict.get() :

d = dict()

for i in xrange(100):
    key = i % 10
    d[key] = d.get(key, 0) + 1

... et si vous voulez toujours assurer une valeur par défaut pour n'importe quelle clé, vous pouvez utiliser defaultdict de la collections module, comme ceci :

from collections import defaultdict

d = defaultdict(lambda: 0)

for i in xrange(100):
    d[i % 10] += 1

... mais en général, le in Le mot-clé est le meilleur moyen de le faire.

82 votes

J'utilise généralement get si j'ai l'intention de sortir l'article du dictionnaire de toute façon. Il est inutile d'utiliser in et en sortant l'article du dictionnaire.

82 votes

Je suis tout à fait d'accord. Mais si vous avez seulement besoin de savoir si une clé existe, ou si vous devez faire la distinction entre un cas où la clé est définie et un cas où vous utilisez une valeur par défaut, in est le meilleur moyen de le faire.

5 votes

Référence pour cette réponse se trouve dans les docs python

1632voto

Jason Baker Points 56682

Vous n'avez pas besoin d'appeler les clés :

if 'key1' in dict:
  print "blah"
else:
  print "boo"

Cela sera beaucoup plus rapide car il utilise le hachage du dictionnaire au lieu d'effectuer une recherche linéaire, ce que ferait l'appel des clés.

280voto

Michael Aaron Safyan Points 45071

Il y a deux façons différentes de procéder :

  1. key **in** dict
  2. dict.has_key(key)

Vous pouvez également consulter le site Référence rapide à Python .

EDIT :

Comme indiqué, "has_key" est déprécié dans Python 3.0+.

106voto

Greg Hewgill Points 356191

Vous pouvez raccourcir cela :

if 'key1' in dict:
    ...

Toutefois, il s'agit au mieux d'une amélioration cosmétique. Pourquoi pensez-vous que ce n'est pas la meilleure solution ?

113 votes

C'est beaucoup plus qu'une amélioration cosmétique. Le temps nécessaire pour trouver une clé en utilisant cette méthode est O(1) alors que l'appel des clés générerait une liste et serait O(n).

5 votes

Le O(1) ne semble pas tout à fait juste. Êtes-vous sûr que ce n'est pas quelque chose comme O(log n) ?

15 votes

C'est la complexité d'une seule recherche de dict, qui est en moyenne O(1) et au pire O(n). .list() sera toujours O(n). wiki.python.org/moin/TimeComplexity (en anglais)

61voto

David Berger Points 5459

Je recommande d'utiliser le setdefault à la place. Il semble qu'elle fera tout ce que vous voulez.

>>> d = {'foo':'bar'}
>>> q = d.setdefault('foo','baz') #Do not override the existing key
>>> print q #The value takes what was originally in the dictionary
bar
>>> print d
{'foo': 'bar'}
>>> r = d.setdefault('baz',18) #baz was never in the dictionary
>>> print r #Now r has the value supplied above
18
>>> print d #The dictionary's been updated
{'foo': 'bar', 'baz': 18}

9 votes

Qu'est-ce que setdefault ont à voir avec la question de l'OP ?

20 votes

@hughdbrown "Je voulais tester si une clé existe dans un dictionnaire avant de mettre à jour la valeur de cette clé." Parfois, les posts incluent du code qui génère une rafale de réponses à quelque chose qui n'est pas tout à fait l'objectif initial. Pour accomplir l'objectif énoncé dans la première phrase, setdefault est la méthode la plus efficace, même si ce n'est pas un remplacement immédiat de l'exemple de code posté.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X