J'ai lu les exemples dans les documents python, mais je n'arrive toujours pas à comprendre ce que cette méthode signifie. Quelqu'un peut-il aider? Voici deux exemples tirés des documents python
>>> 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
pour quoi faire?
default_factory = None
fois que vous avez terminé de remplir le defaultdict. Voir cette question .Réponses:
Habituellement, un dictionnaire Python lance un
KeyError
si vous essayez d'obtenir un élément avec une clé qui n'est pas actuellement dans le dictionnaire. Ledefaultdict
contraste créera simplement tous les éléments auxquels vous essayez d'accéder (à condition bien sûr qu'ils n'existent pas encore). Pour créer un tel élément "par défaut", il appelle l'objet fonction que vous passez au constructeur (plus précisément, il s'agit d'un objet "appelable" arbitraire, qui comprend des objets fonction et type). Pour le premier exemple, les éléments par défaut sont créés à l'aide deint()
, qui renverra l'objet entier0
. Pour le deuxième exemple, les éléments par défaut sont créés à l'aide delist()
, qui renvoie un nouvel objet de liste vide.la source
d.get(key, default)
ne modifiera jamais votre dictionnaire - il renverra simplement la valeur par défaut et laissera le dictionnaire inchangé.defaultdict
, d'autre part, insérera une clé dans le dictionnaire si elle n'y est pas encore. C'est une grande différence; voir les exemples dans la question pour comprendre pourquoi.defaultdict
appelle le constructeur que vous passez. Si vous passez un type aT
, les valeurs seront construites à l'aide deT()
. Tous les types ne peuvent pas être construits sans passer de paramètres. Si vous voulez construire un tel type, vous avez besoin d'une fonction wrapper, ou quelque chose commefunctools.partial(T, arg1, arg2)
.defaultdict
signifie que si une clé n'est pas trouvée dans le dictionnaire, au lieu d'KeyError
être lancée, une nouvelle entrée est créée. Le type de cette nouvelle entrée est donné par l'argument de defaultdict.Par exemple:
la source
0
l'entier, s'il l'était,someddict = defaultdict(list)
il revient[ ]
. 0 est-il l'entier par défaut? Ou [] la liste par défaut?0
est immuable - dans CPython toutes les valeurs de-5
à256
sont des singletons mis en cache mais c'est un comportement spécifique à l'implémentation - dans les deux cas, une nouvelle instance est "créée" à chaque fois avecint()
oulist()
. De cette façon,d[k].append(v)
peut fonctionner sans remplir le dictionnaire avec des références à la même liste, ce qui rendraitdefaultdict
presque inutile. Si tel était le comportement,defaultdict
prendrait une valeur, pas un lambda, comme paramètre. (Désolé pour la terrible explication!)defaultdict
"Le dictionnaire standard inclut la méthode setdefault () pour récupérer une valeur et é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 à renvoyer) à l'avance lorsque le conteneur est initialisé."tel que défini par Doug Hellmann dans The Python Standard Library by Example
Comment utiliser defaultdict
Importer defaultdict
Initialiser defaultdict
Initialisez-le en passant
ou
Comment ça fonctionne
Comme une classe enfant de dictionnaire standard, elle peut exécuter toutes les mêmes fonctions.
Mais en cas de passage d'une clé inconnue, il renvoie la valeur par défaut au lieu de l'erreur. Par exemple:
Si vous souhaitez modifier la valeur par défaut, remplacez default_factory:
ou
Exemples dans la question
Exemple 1
Comme int a été passé en tant que default_factory, toute clé inconnue renverra 0 par défaut.
Maintenant que la chaîne est passée dans la boucle, cela augmentera le nombre de ces alphabets en d.
Exemple 2
Comme une liste a été passée en tant que default_factory, toute clé inconnue (inexistante) renverra [] (ie. List) par défaut.
Maintenant que la liste des tuples est passée dans la boucle, elle ajoutera la valeur dans le d [color]
la source
Les dictionnaires sont un moyen pratique de stocker des données pour une récupération ultérieure par nom (clé). Les clés doivent être des objets uniques et immuables, et sont généralement des chaînes. Les valeurs d'un dictionnaire peuvent être n'importe quoi. Pour de nombreuses applications, les valeurs sont des types simples tels que des entiers et des chaînes.
Cela devient plus intéressant lorsque les valeurs d'un dictionnaire sont des collections (listes, dict, etc.) Dans ce cas, la valeur (une liste ou un dict vide) doit être initialisée la première fois qu'une clé donnée est utilisée. Bien que cela soit relativement facile à faire manuellement, le type defaultdict automatise et simplifie ces types d'opérations. Un defaultdict fonctionne exactement comme un dict normal, mais il est initialisé avec une fonction («usine par défaut») qui ne prend aucun argument et fournit la valeur par défaut pour une clé inexistante.
Un défaut ne déclenchera jamais une erreur de clé. Toute clé qui n'existe pas obtient la valeur renvoyée par la fabrique par défaut.
Voici un autre exemple sur Comment utiliser defaultdict, nous pouvons réduire la complexité
En conclusion, chaque fois que vous avez besoin d'un dictionnaire et que la valeur de chaque élément doit commencer par une valeur par défaut, utilisez un defaultdict.
la source
Il y a une grande explication des défauts par défaut ici: http://ludovf.net/blog/python-collections-defaultdict/
Fondamentalement, les paramètres int et list sont des fonctions que vous passez. N'oubliez pas que Python accepte les noms de fonction comme arguments. int renvoie 0 par défaut et list renvoie une liste vide lorsqu'elle est appelée avec des parenthèses.
Dans les dictionnaires normaux, si dans votre exemple j'essaie d'appeler
d[a]
, j'obtiendrai une erreur (KeyError), car seules les clés m, s, i et p existent et la clé a n'a pas été initialisée. Mais dans un dict par défaut, il prend un nom de fonction comme argument, lorsque vous essayez d'utiliser une clé qui n'a pas été initialisée, il appelle simplement la fonction que vous avez transmise et attribue sa valeur de retour comme valeur de la nouvelle clé.la source
Étant donné que la question porte sur «comment cela fonctionne», certains lecteurs voudront peut-être voir plus d'écrous et de boulons. Plus précisément, la méthode en question est la
__missing__(key)
méthode. Voir: https://docs.python.org/2/library/collections.html#defaultdict-objects .Plus concrètement, cette réponse montre comment utiliser de
__missing__(key)
manière pratique: https://stackoverflow.com/a/17956989/1593924Pour clarifier ce que signifie «appelable», voici une session interactive (à partir de 2.7.6 mais devrait également fonctionner en v3):
C'était l'utilisation la plus courante de defaultdict (à l'exception de l'utilisation inutile de la variable x). Vous pouvez faire la même chose avec 0 comme valeur par défaut explicite, mais pas avec une valeur simple:
Au lieu de cela, ce qui suit fonctionne car il transmet une fonction simple (il crée à la volée une fonction sans nom qui ne prend aucun argument et renvoie toujours 0):
Et avec une valeur par défaut différente:
la source
Mon propre 2 ¢: vous pouvez également sous-classer defaultdict:
Cela pourrait être utile pour des cas très complexes.
la source
Le comportement de
defaultdict
peut être facilement imité en utilisantdict.setdefault
au lieu ded[key]
dans chaque appel.En d'autres termes, le code:
est équivalent à:
La seule différence est que, en utilisant
defaultdict
, le constructeur de liste n'est appelé qu'une seule fois, et en utilisantdict.setdefault
le constructeur de liste est appelé plus souvent (mais le code peut être réécrit pour éviter cela, si vraiment nécessaire).Certains diront qu'il y a une considération de performance, mais ce sujet est un champ de mines. Cet article montre qu'il n'y a pas de gros gain de performances dans l'utilisation de defaultdict, par exemple.
OMI, defaultdict est une collection qui ajoute plus de confusion que d'avantages au code. Inutile pour moi, mais d'autres peuvent penser différemment.
la source
L'outil defaultdict est un conteneur de la classe collections de Python. Il est similaire au conteneur de dictionnaire (dict) habituel, mais il a une différence: le type de données des champs de valeur est spécifié lors de l'initialisation.
Par exemple:
Cela imprime:
la source
list
la fonction à appeler pour remplir une valeur manquante, pas le type des objets à créer. Par exemple, pour avoir une valeur par défaut de1
, vous utiliseriezlambda:1
ce qui n'est évidemment pas un type.Je pense que son mieux utilisé à la place d'une déclaration de cas de commutation. Imaginez si nous avons une déclaration de cas de commutation comme ci-dessous:
Il n'y a pas d'
switch
instructions de cas disponibles en python. Nous pouvons obtenir le même résultat en utilisantdefaultdict
.Il imprime:
Dans l'extrait ci-dessus
dd
n'a pas de clés 4 ou 5 et donc il imprime une valeur par défaut que nous avons configurée dans une fonction d'assistance. C'est bien plus agréable qu'un dictionnaire brut où unKeyError
est lancé si la clé n'est pas présente. De cela, il est évident quedefaultdict
plus comme une déclaration de cas de commutation où nous pouvons éviter unif-elif-elif-else
bloc compliqué .Un autre bon exemple qui m'a beaucoup impressionné sur ce site est:
Si nous essayons d'accéder à des éléments autres que
eggs
etspam
nous obtiendrons un compte de 0.la source
Sans
defaultdict
, vous pouvez probablement affecter de nouvelles valeurs à des clés invisibles mais vous ne pouvez pas les modifier. Par exemple:la source
Eh bien, defaultdict peut également augmenter l'erreur de clé dans le cas suivant:
N'oubliez pas de donner un argument à defaultdict comme defaultdict (int).
la source
Le dictionnaire standard inclut la méthode setdefault () pour récupérer une valeur et é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 dès que le conteneur est initialisé.
Cela fonctionne bien tant qu'il est approprié que toutes les clés aient la même valeur par défaut. Cela peut être particulièrement utile si la valeur par défaut est un type utilisé pour agréger ou accumuler des valeurs, comme une liste, un ensemble ou même un entier. La documentation standard de la bibliothèque comprend plusieurs exemples d'utilisation de defaultdict de cette façon.
la source
En bref:
defaultdict(int)
- l'argument int indique que les valeurs seront de type int.defaultdict(list)
- la liste d'arguments indique que les valeurs seront de type liste.la source
La documentation et l'explication sont assez explicites:
http://docs.python.org/library/collections.html#collections.defaultdict
La fonction type (int / str etc.) passée en argument est utilisée pour initialiser une valeur par défaut pour une clé donnée où la clé n'est pas présente dans le dict.
la source