Pythonic Moyen de Convertir Dictionnaire namedtuple, ou un Autre Hashable dict-like?
J'ai un dictionnaire comme:
d = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
que je voudrais convertir en namedtuple.
Ma démarche actuelle est, avec le code suivant
namedTupleConstructor = namedtuple('myNamedTuple', ' '.join(sorted(d.keys())))
nt= namedTupleConstructor(**d)
qui produit
myNamedTuple(a=1, b=2, c=3, d=4)
Cela fonctionne très bien pour moi (je pense), mais je manque un intégré tel que...
nt = namedtuple.from_dict() ?
Mise à JOUR: comme expliqué dans les commentaires, ma raison de vouloir convertir mon dictionnaire à un namedtuple est de sorte qu'il devient hashable, mais encore utilisable d'une manière générale comme un dict.
- Selon la documentation, il n'y a pas un moyen plus court. Cependant, vous pouvez étendre la classe et de mettre en œuvre la méthode.
- Avec namedtuples, vous êtes censé créer de la namedtuple type une fois et l'utiliser à plusieurs reprises, de ne pas générer un nouveau namedtuple taper à chaque fois. La génération d'une nouvelle namedtuple type de tous les temps est lent et l'emporte sur tout l'espace de prestations.
- sans doute, l'utilisateur dispose de nombreuses dicts avec les mêmes touches.
- Il ne va pas être intégré dans des constructions du type et de la n-uplet dans le même temps, parce que vous êtes censé pour réutiliser le type.
- Totalement d'accord avec @user2357112. La définition d'un nommé tuple du dictionnaire est un one-liner, nt= namedTupleConstructor(**d). La première ligne est la définition d'une nouvelle classe, qui est censé être ré-utilisé.
Vous devez vous connecter pour publier un commentaire.
Pour créer la sous-classe, vous pouvez simplement passer les clés d'une dict directement:
Maintenant de créer des instances de ce dict, ou d'autres dicts avec les touches correspondantes:
Attention: namedtuples comparer sur uniquement les valeurs de (ordonnée). Ils sont conçus pour être une baisse-dans le remplacement régulier de n-uplets, avec attribut nommé d'accès comme une fonction supplémentaire. Les noms de champ ne seront pas considérés lors de la prise de l'égalité des comparaisons. Ce qui diffère de l'
dict
de comparaison d'égalité, qui prennent en compte les clés, et il peut ne pas être ce que vous avez voulu ni prévu à partir de lanamedtuple
type!Si vous avez seulement une dict, plutôt que d'un tas de dicts partage le même jeu de clés, alors il est inutile de créer ce namedtuple en premier lieu. Vous devriez utiliser un espace de noms de l'objet à la place:
Pour un hashable "attrdict" comme recette, découvrez une gelée boîte:
{'a': 1}
et{'b': 1}
vont être l'égalité, et l'égalité des codes de hachage? Quelque chose commetuple(sorted(d.items()))
oufrozenset(d.items())
peut être plus approprié. Ils vont également gérer les clés qui ne sont pas valide identifiants Python, comme'for'
ou3
.frozenset
chose serait en mesure de gérer unorderable clés.) Le namedtuples vous êtes la construction ne comprennent pas les clés dans les tuples eux-mêmes.namedtuple
constructeur crée une nouvelle sous-classe à chaque fois que vous prenez un énorme gain de performance sur la définition d'une sous-classe de première avectyping.NamedTuple
et ensuite de faireMyTuple(**d)
si vous le faites plusieurs foisVous pouvez utiliser cette fonction pour gérer imbriqués les dictionnaires:
Check this out:
Exceptions pour les noms incorrects ou invalid argument de comptage est assuré par
__init__
denamedtuple
.Test avec py.test:
Bien que j'aime @fuggy_yama réponse, avant de le lire j'ai obtenu mon propre fonction, donc, je laisse ici de montrer qu'une approche différente. Il gère aussi imbriquée
namedtuples
Accès
obj.name.firstName
,obj.id
Cela fonctionne pour imbriquée dictionnaire avec tous les types de données.