329 votes

Vérifie si une clé donnée existe déjà dans un dictionnaire et l'incrémente

Étant donné un dictionnaire, comment puis-je savoir si une clé donnée de ce dictionnaire a déjà été définie par une valeur autre que None ?

C'est-à-dire que je veux faire ça :

my_dict = {}

if (my_dict[key] != None):
  my_dict[key] = 1
else:
  my_dict[key] += 1

C'est-à-dire que je veux incrémenter la valeur s'il y en a déjà une, ou la mettre à 1 sinon.

12 votes

Petit problème de code : le code met mon_dict[key] à 1 s'il y a déjà quelque chose, et l'incrémente dans le cas contraire. Je pense que vous voulez ==, pas !=.

355voto

dF. Points 29787

Vous êtes à la recherche de collections.defaultdict (disponible pour Python 2.5+). Ce site

from collections import defaultdict

my_dict = defaultdict(int)
my_dict[key] += 1

fera ce que vous voulez.

Pour le Python ordinaire dict s, s'il n'y a pas de valeur pour une clé donnée, vous allez no obtenir None lors de l'accès au dict -- un KeyError sera relevé. Donc, si vous voulez utiliser un dict Au lieu de votre code, vous utiliseriez

if key in my_dict:
    my_dict[key] += 1
else:
    my_dict[key] = 1

8 votes

Selon son exemple, il devrait suffire de définir "defaultdict(lambda : 0)" et de sauter toute la clause "if".

0 votes

Cela fonctionne, mais confond les clés et les valeurs (ce qui rend la lecture un peu bizarre). Quelque_valeur' devrait être 'quelque_clé'.

0 votes

@nailer : corrigé, merci. J'avais initialement utilisé 'some_value' puisque c'est le nom de la variable dans la question, mais je suis d'accord, c'est plus clair maintenant.

350voto

Andrew Wilkinson Points 4875

Je préfère faire cela en une seule ligne de code.

my\_dict = {}

my\_dict\[some\_key\] = my\_dict.get(some\_key, 0) + 1

Les dictionnaires ont une fonction, get, qui prend deux paramètres - la clé que vous voulez, et une valeur par défaut si elle n'existe pas. Je préfère cette méthode à defaultdict car vous ne voulez gérer que le cas où la clé n'existe pas dans cette ligne de code, pas partout.

2 votes

Je préfère cette solution à la réponse choisie car elle ne nécessite pas l'installation d'une autre dépendance.

2 votes

@Erol defaultdict es qui fait partie de la bibliothèque standard de Python . Aucune installation n'est donc nécessaire !

50voto

Eli Bendersky Points 82298

Vous avez besoin de la key in dict idiome pour cela.

if key in my_dict and not (my_dict[key] is None):
  # do something
else:
  # do something else

Cependant, vous devriez probablement envisager d'utiliser defaultdict (comme dF l'a suggéré).

1 votes

Veuillez noter que dans la version 2.6 au moins, has_key() a été supprimé au profit de key in d. Je pense qu'il en était de même dans la version 2.5.

0 votes

Notez que l'on peut écrire my_dict[key] is not None ce qui est plus clair (du moins à mon avis).

0 votes

@brandizzi - d'accord, if key in my_dict and my_dict[key]:

14voto

ryeguy Points 24980

D'accord avec cgoldberg. Voici comment je procède :

try:
    dict[key] += 1
except KeyError:
    dict[key] = 1

Donc, soit vous le faites comme ci-dessus, soit vous utilisez un dict par défaut comme d'autres l'ont suggéré. N'utilisez pas d'instructions if. Ce n'est pas Python.

8 votes

En quoi les instructions if ne sont-elles pas pythoniques ?

2 votes

Je pense que c'est un cas où l'EAFP de Python n'est pas le meilleur moyen. Votre exemple ci-dessus comporte du code dupliqué ; que se passera-t-il si un jour nous voulons +=2 o -=1 ? Vous devez vous souvenir de modifier les deux lignes. Cela peut sembler anodin maintenant, mais c'est le genre de petits bogues "anodins" qui peuvent revenir vous mordre.

3 votes

Cela a l'air bien et fonctionne bien, mais j'évite habituellement de le faire de cette façon parce que je pensais que l'overhead dans la gestion des exceptions dans les langues est toujours un ordre de grandeur plus grand que la consultation de la table de hachage qui détermine si l'élément existe ou non dans le dictionnaire.

11voto

bortzmeyer Points 12246

Comme vous pouvez le voir dans les nombreuses réponses, il existe plusieurs solutions. Un exemple de LBYL (look before you leap) n'a pas encore été mentionné, la méthode has_key() :

my_dict = {}

def add (key):
    if my_dict.has_key(key):
        my_dict[key] += 1
    else:
        my_dict[key] = 1

if __name__ == '__main__':
    add("foo")
    add("bar")
    add("foo")
    print my_dict

6 votes

Has_key() est plus lent que l'opérateur 'in' et est moins lisible.

9 votes

...et il a été déprécié dans Python 2.6 et supprimé dans Python 3.

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