web-dev-qa-db-fra.com

Comment ajouter ou incrémenter une entrée de dictionnaire?

Je suis en train de me réengager avec Python après une longue absence et j'adore ça. Cependant, je me retrouve à traverser un schéma encore et encore. Je continue de penser qu'il doit y avoir une meilleure façon de exprimer ce que je veux et que je le fais probablement mal.

Le code que j'écris est sous la forme suivante:

# foo is a dictionary
if foo.has_key(bar):
  foo[bar] += 1
else:
  foo[bar] = 1

J'écris beaucoup cela dans mes programmes. Ma première réaction est de le pousser vers une fonction d'aide, mais si souvent les bibliothèques python fournissent déjà des choses comme ça.

Y a-t-il un petit truc de syntaxe simple qui me manque? Ou est-ce ainsi que cela doit être fait?

56
cursa

Utilisez un defaultdict:

from collections import defaultdict

foo = defaultdict(int)
foo[bar] += 1

Dans Python> = 2.7, vous avez également une classe Counter distincte à ces fins. Pour Python 2.5 et 2.6, vous pouvez utilisez son version rétroportée .

96
Tamás

La méthode dictget() prend un deuxième paramètre facultatif qui peut être utilisé pour fournir une valeur par défaut si la clé demandée n'est pas trouvée:

foo[bar] = foo.get(bar, 0) + 1
95
sth

J'ai fait des comparaisons de temps. À peu près égal. La commande unilatérale .get() est cependant la plus rapide.

Production:

get 0.543551800627
exception 0.587318710994
haskey 0.598421703081

Code:

import timeit
import random

RANDLIST = [random.randint(0, 1000) for i in range(10000)]

def get():
    foo = {}
    for bar in RANDLIST:
        foo[bar] = foo.get(bar, 0) + 1


def exception():
    foo = {}
    for bar in RANDLIST:
        try:
            foo[bar] += 1
        except KeyError:
            foo[bar] = 1


def haskey():
    foo = {}
    for bar in RANDLIST:
        if foo.has_key(bar):
            foo[bar] += 1
        else:
            foo[bar] = 1


def main():
    print 'get', timeit.timeit('get()', 'from __main__ import get', number=100)
    print 'exception', timeit.timeit('exception()', 'from __main__ import exception', number=100)
    print 'haskey', timeit.timeit('haskey()', 'from __main__ import haskey', number=100)


if __== '__main__':
    main()
5
user297250

Pour Python> = 2.5, vous pouvez effectuer les opérations suivantes:

foo[bar] = 1 if bar not in foo else foo[bar]+1
3
thetaiko

Vous pouvez également profiter de la structure de contrôle dans la gestion des exceptions. Une exception KeyError est levée par un dictionnaire lorsque vous essayez d'affecter une valeur à une clé inexistante:

my_dict = {}
try:
    my_dict['a'] += 1
except KeyError, err:    # in 2.6: `except KeyError as err:`
    my_dict['a'] = 1
3
Santa