Étant donné un dictionnaire, comment puis-je savoir si une clé donnée dans ce dictionnaire a déjà été définie sur une valeur non nulle?
C'est-à-dire que je veux faire ceci:
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.
Réponses:
Vous recherchez
collections.defaultdict
(disponible pour Python 2.5+). Cefera ce que vous voulez.
Pour Python régulière
dict
s, s'il n'y a pas de valeur pour une clé donnée, vous n'obtenez lorsque vous accédez au dict - un ressusciteront. Donc, si vous souhaitez utiliser un régulier , au lieu de votre code, vous utiliseriezNone
KeyError
dict
la source
dict
, vous pouvez le fairemy_dict[key] = my_dict.get(key, 0) + 1
.Je préfère le faire dans une seule ligne de code.
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 seule ligne de code, pas partout.
la source
J'aime personnellement utiliser
setdefault()
la source
setdefault
est génial. Il ne modifie pas la valeur si une est déjà définie poursome_key
. Par exemple,d={1:2}; d.setdefault(1, 0)
ne perturbe pas la valeur ded[1]
.Vous avez besoin de l'
key in dict
idiome pour cela.Cependant, vous devriez probablement envisager d'utiliser
defaultdict
(comme suggéré par dF).la source
my_dict[key] is not None
, ce qui est plus clair (àif key in my_dict and my_dict[key]:
Pour répondre à la question " comment puis-je savoir si un index donné dans ce dict a déjà été défini sur une valeur non nulle ", je préférerais ceci:
Cela est conforme au concept déjà invoqué d'EAFP (plus facile de demander pardon puis permission). Cela évite également la recherche de clé en double dans le dictionnaire comme ce serait le cas dans
key in my_dict and my_dict[key] is not None
ce qui est intéressant si la recherche est coûteuse.Pour le problème réel que vous avez posé, c'est-à-dire incrémenter un int s'il existe, ou le définir sur une valeur par défaut sinon, je recommande également le
comme dans la réponse d'Andrew Wilkinson.
Il existe une troisième solution si vous stockez des objets modifiables dans votre dictionnaire. Un exemple courant pour cela est un multimap , où vous stockez une liste d'éléments pour vos clés. Dans ce cas, vous pouvez utiliser:
Si une valeur pour key n'existe pas dans le dictionnaire, la méthode setdefault la définira sur le deuxième paramètre de setdefault. Il se comporte exactement comme un my_dict [clé] standard, renvoyant la valeur de la clé (qui peut être la nouvelle valeur définie).
la source
D'accord avec cgoldberg. Comment je fais:
Donc, faites-le comme ci-dessus ou utilisez un dict par défaut comme d'autres l'ont suggéré. N'utilisez pas d'instructions if. Ce n'est pas Pythonic.
la source
+=2
ou-=1
? Vous devez vous rappeler de changer les deux lignes. Cela peut sembler anodin maintenant, mais ce sont le genre de petits bugs stupides qui peuvent revenir vous mordre.Comme vous pouvez le voir dans les nombreuses réponses, il existe plusieurs solutions. Une instance de LBYL (regardez avant de sauter) n'a pas encore été mentionnée, la méthode has_key ():
la source
La façon dont vous essayez de le faire s'appelle LBYL (regardez avant de sauter), car vous vérifiez les conditions avant d'essayer d'augmenter votre valeur.
L'autre approche est appelée EAFP (plus facile de demander pardon puis permission). Dans ce cas, vous essayez simplement l'opération (incrémentez la valeur). S'il échoue, vous interceptez l'exception et définissez la valeur sur 1. Il s'agit d'une façon légèrement plus Pythonique de le faire (IMO).
http://mail.python.org/pipermail/python-list/2003-May/205182.html
la source
Un peu tard mais ça devrait marcher.
la source
Cela ne répond pas directement à la question, mais pour moi, il semble que vous souhaitiez peut-être la fonctionnalité des collections .
Cela se traduit par la sortie
la source
defaultdict(int)
avec certaines fonctionnalités supplémentaires, il fonctionnerait donc parfaitement lorsqu'il s'agit exclusivement d'entiers, mais vous ne montrez aucun des comportements pertinents.Voici une ligne que j'ai récemment trouvée pour résoudre ce problème. Il est basé sur la méthode du dictionnaire setdefault :
la source
Je le cherchais, je ne l'ai pas trouvé sur le web puis j'ai tenté ma chance avec Try / Error et je l'ai trouvé
la source
__contains__
dans un code de production. btw.__contains__
revient à utiliseris
.my_dict.__contains__(some_key)
est équivalent àsome_key in my_dict
, n'est pas une surcharge pour l'in
opérateur nonis