J'ai exécuté le code suivant:
from collections import defaultdict
lst = list(range(0,5))
d = defaultdict(lst)
et j'ai eu cette erreur:
TypeError: first argument must be callable or None
Veuillez aider
Pour un defaultdict
le valeur par défaut est généralement pas vraiment une valeur, c'est un sine: une méthode qui génère une nouvelle valeur . Vous pouvez résoudre ce problème en utilisant une expression lambda qui génère une liste:
lst = lambda:list(range(0,5))
d = defaultdict(lst)
C'est aussi une bonne idée ici, car sinon toutes les valeurs par défaut serait référence à la même liste. Par exemple ici:
d[1].append(14)
pas aura un impact sur d[2]
(étant donné que d[1]
et d[2]
n'existaient pas).
Vous pouvez cependant y parvenir avec:
val = list(range(0,5))
lst = lambda:val
d = defaultdict(lst)
Mais cela peut avoir des effets secondaires indésirables: si vous effectuez ici d[1].append(14)
alors d[2]
Sera [1,2,3,4,5,14]
Et d[1] is d[2]
Sera 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]
True
tandis que:
$ 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]
False
Vous devriez faire du paramètre un appelable, disons, en utilisant lambda
:
from collections import defaultdict
d = defaultdict(lambda: list(range(0,5)))
print(d[0])
# [0, 1, 2, 3, 4]
Dictionnaire par défaut accepte l'appelable comme premier argument (qui est la fabrique par défaut pour les valeurs non définies), donc ce que vous voulez faire est l'étape suivante:
from collections import defaultdict
default_factory = (lambda: list(range(0,5))
d = defaultdict(default_factory)
En savoir plus sur callable dans Qu'est-ce qu'un "callable" en Python? SO question.