Existe-t-il un moyen d'avoir un defaultdict(defaultdict(int))
afin de faire fonctionner le code suivant?
for x in stuff:
d[x.a][x.b] += x.c_int
d
doit être construit de manière ad hoc, en fonction des éléments x.a
et x.b
.
Je pourrais utiliser:
for x in stuff:
d[x.a,x.b] += x.c_int
mais je ne pourrais pas utiliser:
d.keys()
d[x.a].keys()
python
collections
Jonathan
la source
la source
Réponses:
Oui comme ça:
L'argument d'un
defaultdict
(dans ce cas estlambda: defaultdict(int)
) sera appelé lorsque vous essayez d'accéder à une clé qui n'existe pas. La valeur de retour de celle-ci sera définie comme la nouvelle valeur de cette clé, ce qui signifie dans notre cas que la valeur ded[Key_doesnt_exist]
seradefaultdict(int)
.Si vous essayez d'accéder à une clé de ce dernier defaultdict, c'est-
d[Key_doesnt_exist][Key_doesnt_exist]
à- dire qu'elle retournera 0, qui est la valeur de retour de l'argument du dernier defaultdict, c'est-à-direint()
.la source
defaultdict
(dans ce cas estlambda : defaultdict(int)
) sera appelé lorsque vous essayez d'accéder à une clé qui n'existe pas et sa valeur de retour sera définie comme la nouvelle valeur de cette clé, ce qui signifie dans dans notre cas, la valeur ded[Key_dont_exist]
seradefaultdict(int)
, et si vous essayez d'accéder à une clé de ce dernier défaut, c'est-d[Key_dont_exist][Key_dont_exist]
à- dire qu'elle renverra 0, qui est la valeur de retour de l'argument du dernier,defaultdict
c'est-à- dire que j'espère que cela vous auraint()
été utile.defaultdict
devrait être une fonction.defaultdict(int)
est un dictionnaire, tandis que salambda: defaultdict(int)
fonction renvoie un dictionnaire.defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
Le paramètre du constructeur defaultdict est la fonction qui sera appelée pour construire de nouveaux éléments. Alors utilisons un lambda!
Depuis Python 2.7, il existe une solution encore meilleure en utilisant Counter :
Quelques bonus
Pour plus d'informations, consultez PyMOTW - Collections - Types de données de conteneur et documentation Python - collections
la source
d = defaultdict(lambda : Counter())
plutôt qued = defaultdict(lambda : defaultdict(int))
de traiter spécifiquement le problème tel qu'il a été posé à l'origine.d = defaultdict(Counter())
pas besoin d'un lambda dans ce casCounter
objet. Soit:d = defaultdict(Counter)
Je le trouve un peu plus élégant à utiliser
partial
:Bien sûr, c'est la même chose qu'une lambda.
la source
Pour référence, il est possible d'implémenter une
defaultdict
méthode d'usine imbriquée générique via:La profondeur définit le nombre de dictionnaires imbriqués avant que le type défini dans ne
default_factory
soit utilisé. Par exemple:la source
ndd = nested_defaultdict(dict) .... ndd['a']['b']['c']['d'] = 'e'
lancersKeyError: 'b'
depth=0
, qui peut ne pas toujours être souhaité si la profondeur est inconnue au moment de l'appel. Facilement réparable en ajoutant une ligneif not depth: return default_factory()
, en haut de la fonction, bien qu'il existe probablement une solution plus élégante.Les réponses précédentes ont porté sur la façon de créer un niveau à deux niveaux ou n
defaultdict
. Dans certains cas, vous en voulez un infini:Usage:
la source
D'autres ont répondu correctement à votre question sur la façon de faire fonctionner les éléments suivants:
Une alternative serait d'utiliser des tuples pour les clés:
La bonne chose à propos de cette approche est qu'elle est simple et peut être facilement développée. Si vous avez besoin d'une cartographie à trois niveaux, utilisez simplement un tuple à trois éléments pour la clé.
la source