Vérifier si une clé donnée existe déjà dans un dictionnaire et l'incrémenter
-
19-08-2019 - |
Question
À partir d'un dictionnaire, comment puis-je savoir si une clé donnée dans ce dictionnaire a déjà été définie sur une valeur autre que None?
I.e., je veux faire ceci:
my_dict = {}
if (my_dict[key] != None):
my_dict[key] = 1
else:
my_dict[key] += 1
I.e., je souhaite incrémenter la valeur s'il en existe déjà une ou la définir sur 1 sinon.
La solution
Vous recherchez collections.defaultdict
(disponible pour Python 2.5+). Cette
from collections import defaultdict
my_dict = defaultdict(int)
my_dict[key] += 1
fera ce que vous voulez.
Pour les dict
Python normaux, s'il n'y a pas de valeur pour une clé donnée, vous ne obtiendrez pas un Aucun
lors de l'accès au dict - - un KeyError
sera levé. Donc, si vous voulez utiliser un dict
classique, vous utiliserez plutôt
if key in my_dict:
my_dict[key] += 1
else:
my_dict[key] = 1
Autres conseils
Je préfère le faire dans une 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é souhaitée et une valeur par défaut si elle n’existe pas. Je préfère cette méthode à defaultdict car vous souhaitez uniquement gérer le cas où la clé n'existe pas dans cette ligne de code, pas partout.
Personnellement, j'aime bien utiliser setdefault ()
my_dict = {}
my_dict.setdefault(some_key, 0)
my_dict[some_key] += 1
Vous avez besoin de la touche dans dict
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 suggéré par dF).
Pour répondre à la question ", comment puis-je savoir si un index donné de ce dict a déjà été défini sur une valeur autre que None ", je préférerais ceci:
try:
nonNone = my_dict[key] is not None
except KeyError:
nonNone = False
Ceci est conforme au concept déjà invoqué d’EAFP (il est plus facile de demander pardon que l’autorisation). Cela évite également la recherche de clés en double dans le dictionnaire comme dans dans my_dict et my_dict [clé] n’est pas None
, ce qui est intéressant si la recherche coûte cher.
Pour le problème actuel que vous avez posé, c’est-à-dire incrémenter un int s'il existe ou lui attribuer une valeur par défaut sinon, je recommande également la
my_dict[key] = my_dict.get(key, default) + 1
comme dans la réponse d'Andrew Wilkinson.
Il existe une troisième solution si vous stockez des objets modifiables dans votre dictionnaire. carte multiple , où vous stockez une liste d'éléments pour vos clés, est un exemple courant. Dans ce cas, vous pouvez utiliser:
my_dict.setdefault(key, []).append(item)
Si une valeur pour la clé n'existe pas dans le dictionnaire, la méthode setdefault la définira comme second paramètre de setdefault. Il se comporte comme un my_dict [clé] standard, en renvoyant la valeur de la clé (qui peut être la valeur nouvellement définie).
D'accord avec cgoldberg. Comment je le fais est:
try:
dict[key] += 1
except KeyError:
dict[key] = 1
Donc, soit le faire comme ci-dessus, ou utilisez un dict par défaut comme d'autres l'ont suggéré. N'utilisez pas les déclarations if. Ce n'est pas Pythonic.
Comme vous pouvez le constater parmi 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 ():
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
La façon dont vous essayez de le faire s'appelle LBYL (regardez avant de sauter), puisque vous vérifiez les conditions avant d'essayer d'incrémenter votre valeur.
L’autre approche s'appelle EAFP (il est plus facile de demander pardon que d’autoriser). Dans ce cas, il vous suffirait d'essayer l'opération (incrémenter la valeur). En cas d’échec, vous capturez l’exception et définissez la valeur sur 1. C’est une manière légèrement plus pythonique de le faire (IMO).
http://mail.python.org/pipermail /python-list/2003-May/205182.html
Un peu en retard mais cela devrait fonctionner.
my_dict = {}
my_dict[key] = my_dict[key] + 1 if key in my_dict else 1
Cela ne répond pas directement à la question, mais pour moi, il semblerait que vous souhaitiez peut-être utiliser la fonctionnalité de collections.Counter .
from collections import Counter
to_count = ["foo", "foo", "bar", "baz", "foo", "bar"]
count = Counter(to_count)
print(count)
print("acts just like the desired dictionary:")
print("bar occurs {} times".format(count["bar"]))
print("any item that does not occur in the list is set to 0:")
print("dog occurs {} times".format(count["dog"]))
print("can iterate over items from most frequent to least:")
for item, times in count.most_common():
print("{} occurs {} times".format(item, times))
Cela entraîne la sortie
Counter({'foo': 3, 'bar': 2, 'baz': 1})
acts just like the desired dictionary:
bar occurs 2 times
any item that does not occur in the list is set to 0:
dog occurs 0 times
can iterate over items from most frequent to least:
foo occurs 3 times
bar occurs 2 times
baz occurs 1 times
Voici un document que j'ai proposé récemment pour résoudre ce problème. Cette méthode est basée sur la méthode du dictionnaire setdefault :
my_dict = {}
my_dict[key] = my_dict.setdefault(key, 0) + 1
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é
.my_dict = {}
if my_dict.__contains__(some_key):
my_dict[some_key] += 1
else:
my_dict[some_key] = 1