He leído los ejemplos en documentos de Python, pero aún no puedo entender qué significa este método. Alguien puede ayudar? Aquí hay dos ejemplos de los documentos de 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)]
y
>>> 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])]
los parámetros int
y list
son para que?
python
dictionary
default-value
defaultdict
Lanston
fuente
fuente
default_factory = None
después de que haya terminado de llenar el defaultdict. Ver esta pregunta .Respuestas:
Por lo general, un diccionario de Python arroja un
KeyError
si intenta obtener un elemento con una clave que no está actualmente en el diccionario. Por eldefaultdict
contrario, simplemente creará cualquier elemento al que intente acceder (siempre que, por supuesto, todavía no exista). Para crear dicho elemento "predeterminado", llama al objeto de función que pasa al constructor (más precisamente, es un objeto arbitrario "invocable", que incluye objetos de función y tipo). Para el primer ejemplo, los elementos predeterminados se crean utilizandoint()
, lo que devolverá el objeto entero0
. Para el segundo ejemplo, los elementos predeterminados se crean utilizandolist()
, lo que devuelve un nuevo objeto de lista vacío.fuente
d.get(key, default)
nunca modificará su diccionario, solo devolverá el predeterminado y dejará el diccionario sin cambios.defaultdict
, por otro lado, insertará una clave en el diccionario si aún no está allí. Esta es una gran diferencia; Vea los ejemplos en la pregunta para entender por qué.defaultdict
llama al constructor que pase. Si pasa un tipoT
, los valores se construirán usandoT()
. No todos los tipos se pueden construir sin pasar ningún parámetro. Si desea construir dicho tipo, necesita una función de envoltura, o algo asífunctools.partial(T, arg1, arg2)
.defaultdict
significa que si no se encuentra una clave en el diccionario, en lugar deKeyError
ser arrojada, se crea una nueva entrada. El tipo de esta nueva entrada viene dado por el argumento de defaultdict.Por ejemplo:
fuente
0
el entero, si lo fuesomeddict = defaultdict(list)
, regresa[ ]
. ¿Es 0 el entero predeterminado? O [] la lista predeterminada?0
es inmutable: en CPython todos los valores de-5
a256
son caché singletons, pero este es un comportamiento específico de la implementación; en ambos casos, una nueva instancia se "crea" cada vez conint()
olist()
. De esa manera,d[k].append(v)
puede funcionar sin llenar el diccionario con referencias a la misma lista, lo que haríadefaultdict
casi inútil. Si este fuera el comportamiento,defaultdict
tomaría un valor, no una lambda, como parámetro. (¡Perdón por la terrible explicación!)defaultdict
"El diccionario estándar incluye el método setdefault () para recuperar un valor y establecer un valor predeterminado si el valor no existe. Por el contrario,
defaultdict
permite que la persona que llama especifique el valor predeterminado (valor que se devolverá) por adelantado cuando se inicializa el contenedor".como lo definió Doug Hellmann en The Python Standard Library con Example
Cómo usar defaultdict
Importar defaultdict
Inicializar defaultdict
Inicialízalo pasando
o
Cómo funciona
Como es una clase secundaria de diccionario estándar, puede realizar las mismas funciones.
Pero en caso de pasar una clave desconocida, devuelve el valor predeterminado en lugar de error. Por ej .:
En caso de que desee cambiar el valor predeterminado, sobrescriba default_factory:
o
Ejemplos en la pregunta
Ejemplo 1
Como int se ha pasado como default_factory, cualquier clave desconocida devolverá 0 por defecto.
Ahora, a medida que se pasa la cadena en el bucle, aumentará el recuento de esos alfabetos en d.
Ejemplo 2
Como se ha pasado una lista como default_factory, cualquier clave desconocida (inexistente) devolverá [] (es decir, lista) por defecto.
Ahora, a medida que se pasa la lista de tuplas en el bucle, se agregará el valor en d [color]
fuente
Los diccionarios son una forma conveniente de almacenar datos para su posterior recuperación por nombre (clave). Las claves deben ser objetos únicos e inmutables y, por lo general, son cadenas. Los valores en un diccionario pueden ser cualquier cosa. Para muchas aplicaciones, los valores son tipos simples, como enteros y cadenas.
Se vuelve más interesante cuando los valores en un diccionario son colecciones (listas, dictos, etc.) En este caso, el valor (una lista vacía o dict) debe inicializarse la primera vez que se usa una clave determinada. Si bien esto es relativamente fácil de hacer manualmente, el tipo defaultdict automatiza y simplifica este tipo de operaciones. Un defaultdict funciona exactamente como un dict normal, pero se inicializa con una función ("fábrica predeterminada") que no toma argumentos y proporciona el valor predeterminado para una clave inexistente.
Un fallo predeterminado nunca generará un KeyError. Cualquier clave que no exista obtiene el valor devuelto por la fábrica predeterminada.
Aquí hay otro ejemplo sobre cómo usar defaultdict, podemos reducir la complejidad
En conclusión, siempre que necesite un diccionario, y el valor de cada elemento debe comenzar con un valor predeterminado, use un valor predeterminado.
fuente
Aquí hay una gran explicación de los defaultdicts: http://ludovf.net/blog/python-collections-defaultdict/
Básicamente, los parámetros int y list son funciones que pasa. Recuerde que Python acepta nombres de funciones como argumentos. int devuelve 0 por defecto y list devuelve una lista vacía cuando se llama entre paréntesis.
En los diccionarios normales, si en su ejemplo intento llamar
d[a]
, obtendré un error (KeyError), ya que solo existen las teclas m, s, i y p y la tecla a no se ha inicializado. Pero en un caso por defecto, toma el nombre de una función como argumento, cuando intenta usar una clave que no se ha inicializado, simplemente llama a la función que ingresó y asigna su valor de retorno como el valor de la nueva clave.fuente
Dado que la pregunta es sobre "cómo funciona", algunos lectores pueden querer ver más detalles. Específicamente, el método en cuestión es el
__missing__(key)
método. Ver: https://docs.python.org/2/library/collections.html#defaultdict-objects .Más concretamente, esta respuesta muestra cómo utilizarla de
__missing__(key)
manera práctica: https://stackoverflow.com/a/17956989/1593924Para aclarar qué significa 'invocable', aquí hay una sesión interactiva (desde 2.7.6, pero también debería funcionar en v3):
Ese fue el uso más típico de defaultdict (excepto el uso sin sentido de la variable x). Puede hacer lo mismo con 0 como valor predeterminado explícito, pero no con un valor simple:
En cambio, lo siguiente funciona porque pasa una función simple (crea sobre la marcha una función sin nombre que no toma argumentos y siempre devuelve 0):
Y con un valor predeterminado diferente:
fuente
My own 2 ¢: también puedes subclase defaultdict:
Esto podría ser útil para casos muy complejos.
fuente
El comportamiento de
defaultdict
se puede imitar fácilmente endict.setdefault
lugar ded[key]
en cada llamada.En otras palabras, el código:
es equivalente a:
La única diferencia es que, usando
defaultdict
, el constructor de la lista se llama solo una vez, y usandodict.setdefault
el constructor de la lista se llama con más frecuencia (pero el código puede reescribirse para evitar esto, si es realmente necesario).Algunos pueden argumentar que hay una consideración de rendimiento, pero este tema es un campo minado. Esta publicación muestra que no hay una gran ganancia de rendimiento al usar defaultdict, por ejemplo.
En mi opinión, defaultdict es una colección que agrega más confusión que beneficios al código. Inútil para mí, pero otros pueden pensar diferente.
fuente
La herramienta defaultdict es un contenedor en la clase de colecciones de Python. Es similar al contenedor habitual del diccionario (dict), pero tiene una diferencia: el tipo de datos de los campos de valor se especifica en la inicialización.
Por ejemplo:
Esto imprime:
fuente
list
está la función para llamar para completar un valor faltante, no el tipo de los objetos para crear. Por ejemplo, para tener un valor predeterminado de1
, usaría ellambda:1
que obviamente no es un tipo.Creo que es mejor usarlo en lugar de una declaración de cambio de caso. Imagínese si tenemos una declaración de cambio de caso de la siguiente manera:
No hay
switch
declaraciones de casos disponibles en python. Podemos lograr lo mismo usandodefaultdict
.Imprime:
En el fragmento anterior
dd
no tiene las teclas 4 o 5 y, por lo tanto, imprime un valor predeterminado que hemos configurado en una función auxiliar. Esto es bastante mejor que un diccionario sin formato dondeKeyError
se arroja a si la clave no está presente. A partir de esto, es evidente que esdefaultdict
más como una declaración de caso de cambio donde podemos evitarif-elif-elif-else
bloques complicados .Un buen ejemplo más que me impresionó mucho de este sitio es:
Si intentamos acceder a cualquier elemento que no sea
eggs
yspam
obtendremos un recuento de 0.fuente
Sin
defaultdict
, probablemente puede asignar nuevos valores a claves invisibles, pero no puede modificarlo. Por ejemplo:fuente
Bueno, defaultdict también puede generar keyerror en el siguiente caso:
Recuerde siempre dar argumento al defaultdict como defaultdict (int).
fuente
El diccionario estándar incluye el método setdefault () para recuperar un valor y establecer un valor predeterminado si el valor no existe. Por el contrario, defaultdict permite a la persona que llama especificar el valor predeterminado por adelantado cuando se inicializa el contenedor.
Esto funciona bien siempre que sea apropiado que todas las claves tengan el mismo valor predeterminado. Puede ser especialmente útil si el valor predeterminado es un tipo utilizado para agregar o acumular valores, como una lista, un conjunto o incluso int. La documentación de la biblioteca estándar incluye varios ejemplos de uso de defaultdict de esta manera.
fuente
En breve:
defaultdict(int)
- el argumento int indica que los valores serán de tipo int.defaultdict(list)
- la lista de argumentos indica que los valores serán de tipo lista.fuente
La documentación y la explicación se explican por sí mismas:
http://docs.python.org/library/collections.html#collections.defaultdict
La función de tipo (int / str, etc.) pasada como argumento se usa para inicializar un valor predeterminado para cualquier clave dada donde la clave no está presente en el dict.
fuente