É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 autre que Aucune?
I.e., 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.
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 Pythonnormal _ dict
s, s'il n'y a pas de valeur pour une clé donnée, vous obtiendrez pas None
lors de l’accès au dict - une KeyError
sera levée. Donc, si vous voulez utiliser un dict
normal, vous utiliserez plutôt
_if key in my_dict:
my_dict[key] += 1
else:
my_dict[key] = 1
_
Je préfère faire cela dans une ligne de code.
mon_dict = {} mon_dict [une_chonne] = mon_dict.get (une_couche, 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
Pour cela, vous avez besoin du langage key in dict
.
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 non-None ", je préférerais cette:
try:
nonNone = my_dict[key] is not None
except KeyError:
nonNone = False
Cela 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 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 actuel que vous avez posé, c’est-à-dire incrémenter un int s'il existe ou lui attribuer une valeur par défaut, je recommande également la
my_dict[key] = my_dict.get(key, default) + 1
comme dans la réponse de Andrew Wilkinson.
Il existe une troisième solution si vous stockez des objets modifiables dans votre dictionnaire. Un exemple courant pour cela est un carte multiple , dans lequel vous stockez une liste d'éléments pour vos clés. 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 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 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 __== '__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 interceptez l'exception et définissez la valeur sur 1. Il s'agit d'une manière légèrement plus pythonique de le faire (IMO).
http://mail.python.org/pipermail/python-list/2003-May/205182.html
Cela ne répond pas directement à la question, mais pour moi, il semblerait que vous souhaitiez peut-être les fonctionnalités 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 se traduit par 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
Un peu tard mais ça devrait marcher.
my_dict = {}
my_dict[key] = my_dict[key] + 1 if key in my_dict else 1
Voici une ligne que j'ai récemment conçue pour résoudre ce problème. Elle 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