Comment puis-je convertir un defaultdict
number_to_letter
defaultdict(<class 'list'>, {'2': ['a'], '3': ['b'], '1': ['b', 'a']})
être un dict commun?
{'2': ['a'], '3': ['b'], '1': ['b', 'a']}
Comment puis-je convertir un defaultdict
number_to_letter
defaultdict(<class 'list'>, {'2': ['a'], '3': ['b'], '1': ['b', 'a']})
être un dict commun?
{'2': ['a'], '3': ['b'], '1': ['b', 'a']}
Réponses:
Vous pouvez simplement appeler dict
:
>>> a
defaultdict(<type 'list'>, {'1': ['b', 'a'], '3': ['b'], '2': ['a']})
>>> dict(a)
{'1': ['b', 'a'], '3': ['b'], '2': ['a']}
mais rappelez-vous qu'un defaultdict est un dict:
>>> isinstance(a, dict)
True
juste avec un comportement légèrement différent, en ce que lorsque vous essayez d'accéder à une clé qui manque - ce qui soulèverait normalement un KeyError
- le default_factory
est appelé à la place:
>>> a.default_factory
<type 'list'>
C'est ce que vous voyez lorsque vous voyez print a
le côté données du dictionnaire apparaître.
Donc, une autre astuce pour obtenir un comportement plus dictlike sans créer un nouvel objet est de réinitialiser default_factory
:
>>> a.default_factory = None
>>> a[4].append(10)
Traceback (most recent call last):
File "<ipython-input-6-0721ca19bee1>", line 1, in <module>
a[4].append(10)
KeyError: 4
mais la plupart du temps, cela ne vaut pas la peine.
default_factory
? Je n'ai simplement aucune idée de ce qui se passe. Pardon.
default_factory
- c'est la fonction que vous avez passée lorsque vous avez fait le defaultdict
en premier lieu, comme defaultdict(int)
ou defaultdict(list)
. Chaque fois que vous essayez de rechercher une clé dans le dictionnaire, comme a['3']
, par exemple, dans un dictionnaire habituel, vous obtenez la valeur ou cela déclenche une KeyError
exception (comme une erreur, vous indiquant qu'il n'a pas pu trouver cette clé). Mais dans a defaultdict
, il appelle à la place la default_factory
fonction pour créer une nouvelle valeur par défaut (c'est la "valeur par défaut" defaultdict
) pour vous.
pickle
(pour enregistrer des objets python dans un fichier) ne peut pas gérer les defaultdict
s dans de nombreuses circonstances .
Si votre defaultdict est défini de manière récursive, par exemple:
from collections import defaultdict
recurddict = lambda: defaultdict(recurddict)
data = recurddict()
data["hello"] = "world"
data["good"]["day"] = True
encore un autre moyen simple de reconvertir defaultdict en dict est d'utiliser le json
module
import json
data = json.loads(json.dumps(data))
et bien sûr, les valeurs contenues dans votre defaultdict doivent être confinées aux types de données pris en charge par json, mais cela ne devrait pas poser de problème si vous n'avez pas l'intention de stocker des classes ou des fonctions dans le dict.
Si vous voulez même une version récursive pour convertir un récursif defaultdict
en un, dict
vous pouvez essayer ce qui suit:
#! /usr/bin/env python3
from collections import defaultdict
def ddict():
return defaultdict(ddict)
def ddict2dict(d):
for k, v in d.items():
if isinstance(v, dict):
d[k] = ddict2dict(v)
return dict(d)
myddict = ddict()
myddict["a"]["b"]["c"] = "value"
print(myddict)
mydict = ddict2dict(myddict)
print(mydict)
defaultdict(lambda: defaultdict(int))
): {k: dict(v) for k, v in foo.items()}
dict(number_to_letter)