Comment les collections.defaultdict travail?
J'ai lu les exemples en python docs, mais ne peut toujours pas à comprendre ce que cette méthode signifie. Quelqu'un peut-il aider? Voici deux exemples de l'python docs
>>> from collections import defaultdict
>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
... d[k] += 1
...
>>> d.items()
[('i', 4), ('p', 2), ('s', 4), ('m', 1)]
et
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
... d[k].append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
les paramètres int
et list
sont pour quoi?
- BTW, en fonction de votre cas d'utilisation, ne pas oublier pour geler l'defaultdict pour utilisation en lecture seule par l'établissement de ses
default_factory = None
après que vous avez fini de remplir le defaultdict. Voir cette question. - Voir aussi: stackoverflow.com/questions/17215400/...
Vous devez vous connecter pour publier un commentaire.
Généralement, un dictionnaire Python jette un
KeyError
si vous essayez d'obtenir un produit avec une clé qui n'est pas actuellement dans le dictionnaire. Ledefaultdict
en revanche il suffit de créer tous les éléments que vous tentez d'accéder (à condition bien sûr qu'ils n'existent pas encore). Pour créer un tel "défaut" de l'élément, il appelle la fonction de l'objet que vous passer au constructeur (plus précisément, c'est l'arbitraire d'un "callable" objet, qui inclut la fonction et le type d'objets). Pour le premier exemple, par défaut, les éléments sont créés à l'aide deint()
, qui sera de retour l'objet integer0
. Pour le deuxième exemple, par défaut, les éléments sont créés à l'aide delist()
, qui renvoie une nouvelle liste vide de l'objet.defaultdict
, d'autre part, l' insert clé dans le dictionnaire si il n'y est pas encore. C'est une grande différence; voir les exemples dans la question de comprendre pourquoi.defaultdict
signifie que si une clé n'est pas trouvée dans le dictionnaire, alors, au lieu d'unKeyError
jetées, une nouvelle entrée est créée. Le type de cette nouvelle entrée est donné par l'argument de defaultdict.Par exemple:
0
l'entier, si c'étaitsomeddict = defaultdict(list)
il retourne[ ]
. Est 0, la valeur par défaut entier? Ou [ ] la liste par défaut?0
est immuable - Disponible dans toutes les valeurs de-5
à256
de mise en cache des singletons, mais c'est spécifique à l'implémentation de comportement dans les deux cas, une nouvelle instance est "créé" à chaque fois avecint()
oulist()
. De cette façon,d[k].append(v)
peut travailler sans remplir le dictionnaire avec des références à la même liste, ce qui rendraitdefaultdict
presque inutile. Si c'était le comportement,defaultdict
prendrait une valeur, pas une lambda, en tant que paramètre. (Désolé pour le terrible explication!)defaultdict
"Le dictionnaire standard comprend la méthode setdefault() pour récupérer une valeur et d'établir une valeur par défaut si la valeur n'existe pas. En revanche,
defaultdict
permet à l'appelant de spécifier la valeur par défaut(valeur renvoyée) à l'avant lorsque le conteneur est initialisé."tel que défini par Doug Hellmann dans Le Python Standard Library par Exemple
Comment utiliser defaultdict
Importation defaultdict
Initialiser defaultdict
Initialiser en passant
ou
Comment ça fonctionne
Comme c'est un enfant de la classe de dictionnaire standard, il peut effectuer les mêmes fonctions.
Mais en cas de passage d'un inconnu clé, il retourne la valeur par défaut au lieu de l'erreur. Ex:
Dans le cas où vous souhaitez modifier la valeur par défaut remplacer default_factory:
ou
Exemples dans la Question
Exemple 1
Comme int a été adoptée comme default_factory, tout inconnu clé return 0 par défaut.
Maintenant que la chaîne est passée dans la boucle, il faudra augmenter le nombre de ces lettres de l'alphabet. d.
Exemple 2
Qu'une liste a été adoptée comme default_factory, tout inconnu(inexistante) de la clé sera de retour [ ](ie. liste) par défaut.
Maintenant que la liste de tuples est passé dans la boucle, il va ajouter de la valeur dans le d[couleur]
Il ya une grande explication de defaultdicts ici: http://ludovf.net/blog/python-collections-defaultdict/
Fondamentalement, les paramètres int et liste sont des fonctions que vous passez. Rappelez-vous que Python accepte les noms de fonction en tant qu'arguments. int renvoie la valeur 0 par défaut et liste retourne une liste vide lorsqu'il est appelé avec des parenthèses.
Normal dictionnaires, si dans votre exemple, j'ai essayer d'appeler
d[a]
, j'ai un message d'erreur (KeyError), puisque seules les touches m, s, i et p existe et la clé n'a pas été initialisé. Mais dans un defaultdict, il prend un nom de fonction en tant qu'argument, lorsque vous essayez d'utiliser une clé qui n'a pas été initialisé, il appelle simplement la fonction que vous avez passé et assigne sa valeur de retour la valeur de la nouvelle clé.Les dictionnaires sont un moyen pratique pour stocker des données pour une récupération ultérieure par nom (clé). Les clés doivent être uniques, des objets immuables, et sont généralement des chaînes. Les valeurs dans un dictionnaire peut être n'importe quoi. Pour de nombreuses applications, les valeurs sont des types simples comme des entiers et des chaînes de caractères.
Il devient plus intéressant lorsque les valeurs dans un dictionnaire sont des collections (listes, dicts, etc.) Dans ce cas, la valeur (une liste vide ou dict) doit être initialisé la première fois qu'une clé est utilisée. Tout cela est relativement facile de le faire manuellement, le defaultdict type automatise et simplifie ces types d'opérations.
Un defaultdict fonctionne exactement comme un normal dict, mais il est initialisé avec une fonction (“par défaut”) qui ne prend pas d'arguments et fournit la valeur par défaut pour une clé inexistante.
Un defaultdict ne suscitera jamais un KeyError. Une touche qui n'existe pas obtient la valeur retournée par la valeur par défaut d'usine.
Voici un autre exemple sur la Façon dont l'aide defaultdict, nous pouvons réduire la complexité
En conclusion, toutes les fois que vous besoin d'un dictionnaire, et chaque valeur de l'élément doit commencer avec une valeur par défaut, utilisez un defaultdict.
Depuis que la question est "comment ça marche", certains lecteurs veulent voir plus d'écrous et de boulons. Plus précisément, la méthode en question est le
__missing__(key)
méthode. Voir: https://docs.python.org/2/library/collections.html#defaultdict-objects .Plus concrètement, cette réponse montre comment utiliser
__missing__(key)
en pratique:https://stackoverflow.com/a/17956989/1593924
De préciser que "appelable" signifie, voici une session interactive (à partir de 2.7.6 mais devrait fonctionner dans la v3 trop):
Qui a été le plus typique de l'utilisation de defaultdict (sauf pour de l'inutile l'utilisation de la variable x). Vous pouvez faire la même chose avec 0 comme valeur par défaut explicite, mais pas avec une simple valeur:
Au lieu de cela, les ouvrages suivants, parce qu'il passe dans une fonction simple (il crée à la volée un nom de fonction qui ne prend pas d'argument et retourne toujours 0):
Et avec une autre valeur par défaut:
Mon propre 2¢: vous pouvez également sous-classe defaultdict:
Cela pourrait venir dans maniable pour les cas très complexes.
La defaultdict outil est un conteneur dans les collections de la classe de Python. Il est similaire à l'habitude de dictionnaire (dict) conteneur, mais il a une différence: La valeur des champs " type de données est spécifié lors de l'initialisation.
Par exemple:
Cette affiche:
list
est la fonction à appeler pour combler un manque de la valeur, pas le type de l'objet à créer. Par exemple, pour avoir une valeur par défaut de1
, vous pouvez utiliserlambda:1
qui n'est évidemment pas un type.Je pense que c'est mieux utilisé à la place d'un interrupteur de cas. Imaginez si nous avons un interrupteur cas énoncé ci-dessous:
Il n'y a pas de
switch
cas relevés disponibles en python. Nous pouvons réaliser la même chose en utilisantdefaultdict
.Il imprime:
Dans l'extrait ci-dessus
dd
n'a pas de touches 4 ou 5, et donc il imprime une valeur par défaut qui nous avons configuré dans une fonction d'assistance. C'est bien plus agréable que les raw d'un dictionnaire où unKeyError
est levée si la clé n'est pas présente. De ce fait, il est évident quedefaultdict
plus comme un commutateur de cas où l'on peut éviter pas compliquéif-elif-elif-else
blocs.Un bon exemple qui m'a beaucoup impressionné de ce site est:
Si nous essayons d'accéder à tous les éléments autres que
eggs
etspam
nous aurons un nombre de 0.Sans
defaultdict
, vous pouvez probablement affecter de nouvelles valeurs à l'invisible clés, mais vous ne pouvez pas le modifier. Par exemple:Bien, defaultdict peut aussi soulever des keyerror dans le cas suivant:
Toujours n'oubliez pas de donner des arguments à la defaultdict comme defaultdict(int).
Le comportement de
defaultdict
peut être facilement imité en utilisantdict.setdefault
au lieu ded[key]
lors de chaque appel.En d'autres termes, le code:
est équivalent à:
La seule différence est que, en utilisant
defaultdict
, la liste constructeur est appelé qu'une seule fois, et à l'aide dedict.setdefault
la liste constructeur est appelé le plus souvent (mais le code peut être rewriten pour éviter cela, si vraiment nécessaire).Diront certains, il est un facteur de performance, mais ce sujet est un terrain miné. Ce post montre il n'y a pas un gros gain de performances en utilisant defaultdict, par exemple.
De l'OMI, defaultdict est une collection qui ajoute plus de confusion que de bénéfices pour le code. Inutile pour moi, mais d'autres peuvent penser différemment.
En bref:
defaultdict(int)
- l'argument de type int indique que les valeurs de type int.defaultdict(list)
- la liste des arguments indique que les valeurs sont de type liste.Le dictionnaire standard comprend la méthode setdefault() pour récupérer une valeur et d'établir une valeur par défaut si la valeur n'existe pas. En revanche, defaultdict permet à l'appelant de spécifier la valeur par défaut à l'avant lorsque le conteneur est initialisé.
Cela fonctionne bien tant qu'il est approprié pour toutes les clefs pour avoir le même défaut. Il peut être particulièrement utile si la valeur par défaut est le type utilisé pour l'agrégation, l'accumulation des valeurs, comme une liste, ensemble, ou même de type int. La bibliothèque standard de documentation comprend plusieurs exemples de l'utilisation de defaultdict de cette façon.
La documentation et les explications sont assez explicites:
http://docs.python.org/library/collections.html#collections.defaultdict
Le type de la fonction(int/str etc.) passée en argument est utilisé pour initialiser une valeur par défaut pour chaque clé où la clé n'est pas présente dans le dict.