Ejecuté el siguiente código:
from collections import defaultdict lst = list(range(0,5)) d = defaultdict(lst)y obtuve este error:
TypeError: first argument must be callable or NonePor favor ayuda
Para un defaultdict predeterminado, el valor predeterminado generalmente no es realmente un valor , es una fábrica : un método que genera un nuevo valor. Puede resolver este problema utilizando una expresión lambda que genera una lista:
lst = lambda: list(range(0,5)) d = defaultdict(lst)Esta también es una buena idea aquí, ya que de lo contrario todos los valores predeterminados harían referencia a la misma lista . Por ejemplo aquí:
d[1].append(14) no tendrá impacto en d[2] (dado que tanto d[1] como d[2] no existían).
Sin embargo, puede lograr esto con:
val = list(range(0,5)) lst = lambda:val d = defaultdict(lst) Pero esto puede tener efectos secundarios no deseados: si aquí ejecuta d[1].append(14) , entonces d[2] será [1,2,3,4,5,14] y d[1] is d[2] será True :
$ python3 Python 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from collections import defaultdict >>> val = list(range(0,5)) >>> lst = lambda:val >>> d = defaultdict(lst) >>> d[1] [0, 1, 2, 3, 4] >>> d[1].append(14) >>> d[2] [0, 1, 2, 3, 4, 14] >>> d[1] is d[2] Truemientras:
$ python3 Python 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from collections import defaultdict >>> lst = lambda:list(range(0,5)) >>> d = defaultdict(lst) >>> d[1] [0, 1, 2, 3, 4] >>> d[1].append(14) >>> d[2] [0, 1, 2, 3, 4] >>> d[1] is d[2] FalseDebe hacer que el parámetro sea invocable, por ejemplo, usando lambda :
from collections import defaultdict d = defaultdict(lambda: list(range(0,5))) print(d[0]) # [0, 1, 2, 3, 4]El diccionario predeterminado acepta invocable como primer argumento (que es la fábrica predeterminada para valores no definidos), por lo que lo que desea hacer es el siguiente paso:
from collections import defaultdict default_factory = (lambda: list(range(0,5)) d = defaultdict(default_factory)Ver más sobre invocable en ¿Qué es un "invocable" en Python? Entonces pregunta.