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

StackOverflow https://stackoverflow.com/questions/473099

  •  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.

Était-ce utile?

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top