ordered - python 3.6 counter
defaultdict con valor por defecto 1? (2)
Soy nuevo en Python, y leí algunos fragmentos de código de algún lugar. Es una implementación de ordenación por conteo.
El código es el siguiente:
from collections import defaultdict
def sort_colors(A):
ht = {} # a hash map
ht = defaultdict(lambda:0, ht) # with default value 1
for i in A:
ht[i] += 1
ret = []
for k in [0, 1, 2]:
ret.extend([k]*ht[k])
return ret
Como en las dos primeras líneas de la func, es
ht = {}
ht = defaultdict(lambda:0, ht)
No estoy del todo claro acerca de esta inicialización. ¿Podrían ayudarme amablemente a resolverlo? y también, ¿Simplemente reemplazamos estas dos líneas con las siguientes?
ht = defaultdict(int) # default value 0
Creo que solo puedes pasar una función lambda que devuelve 1
d = defaultdict(lambda:1)
Respuesta corta (según la respuesta de Montaro abajo)
defaultdict(lambda:1)
Respuesta larga sobre cómo funciona el defaultdict
.
ht = {}
ht = defaultdict(lambda:0, ht)
defaultdict
s son diferentes de dict
en que cuando intentas acceder a un dict
regular con una clave que no existe, genera un KeyError
.
defaultdict
, sin embargo, no genera un error: crea la clave para ti. ¿Con qué valor? Con el regreso del callabe
como argumento. En este caso, todas las nuevas claves se crearán con el valor 0
(que es el retorno de la función lambda:0
simple lambda
lambda:0
), que también es el mismo retorno de int()
, por lo que en este caso , no habrá diferencia en el cambio de la función por defecto a int()
.
Desglosando esta línea con más detalle: ht = defaultdict(lambda:0, ht)
El primer argumento es una función, que es un objeto llamable. Esta es la función a la que se llamará para crear un nuevo valor para una clave inexistente. El segundo argumento, ht
es opcional y se refiere al diccionario base en el que se construirá el nuevo defaultdict
. Por lo tanto, si tenía algunas claves y valores, el defaultdict
también tendría estas claves con los valores correspondientes. Si intentara acceder a estas claves, obtendría los valores anteriores. Sin embargo, si no pasa el diccionario base, se creará un nuevo valor predeterminado y, por lo tanto, todas las nuevas claves a las que se acceda obtendrán el valor predeterminado devuelto por el llamable.
(En este caso, como ht
es inicialmente un dict
vacío, no habría ninguna diferencia en hacer ht = defaultdict(lambda:0)
, ht = defaultdict(int)
o ht = defaultdict(lambda:0, ht)
: todos construirían el mismo defaultdict
.