Ce qui serait un “gelé dict” l'être?
- Un ensemble figé est un frozenset.
- Une liste bloquée pourrait être un n-uplet.
- Ce serait gelé dict être? Immuable, hashable dict.
Je suppose que cela pourrait être quelque chose comme collections.namedtuple
, mais c'est plus comme une gelée clés dict (une demi-gelée dict). N'est-ce pas?
Un "frozendict" devrait être gelé dictionnaire, il doit avoir keys
, values
, get
, etc., et de soutien in
, for
, etc.
Vous devez vous connecter pour publier un commentaire.
Python n'est pas un builtin frozendict type. Il s'avère que ce ne serait pas utile de trop souvent (même si ce serait probablement encore être utile le plus souvent
frozenset
est).La raison la plus courante de vouloir un tel type est quand memoizing appels de fonction pour les fonctions avec des inconnus d'arguments. La solution la plus courante pour stocker un hashable équivalent d'une dict (où les valeurs sont hashable) est quelque chose comme
tuple(sorted(kwargs.iteritems()))
.Cela dépend du tri de ne pas être un peu fou. Python ne peut pas franchement promesse de tri va en résulter quelque chose de raisonnable ici. (Mais il ne peut pas vous promettre beaucoup d'autre, donc ne vous en faites pas trop.)
Vous pourrait assez facilement faire une sorte de wrapper qui fonctionne un peu comme un dict. Il pourrait ressembler à quelque chose comme
Il devrait fonctionner à merveille:
collections.Mapping
, mais je vois que vous n'avez pas de fonctions de comparaison (eq, gt, lt, cmp, ...). Sauf s'ils sont fournis dans lecollections.Mapping
, vous n'avez pas besoin d'une fonction de hachage. Python utilise automatiquement l'identifiant d'objet comme la clé de hachage.__eq__
et__ne__
mixin, qui nous voulons. Nous avons également voulez, la valeur de hachage. Les valeurs par défaut de l'identité de comparaison pour l'égalité et l'id de hachage dire que deuxFrozenDict
objets qui ont les mêmes données ne peut pas être utilisé utilement comme dict clés. J'ai ajouté un exemple de code qui montre comment cela fonctionne très bien.__hash__
méthode pourrait être légèrement améliorée. Il suffit d'utiliser une variable temporaire lors du calcul de la valeur de hachage, et seulement ensembleself._hash
une fois que vous avez la valeur finale. De cette façon, un autre thread obtenir un hash alors que le premier est le calcul sera tout simplement redondants de calcul, plutôt que d'obtenir une valeur incorrecte.*args
dans__init__
? n'est-ce pas la causedict
erreur d'initialisation?dict
exactement ce que vous appelezFrozenDict
avec l'option -- no erreurs causées par celles qui n'auraient pas été causé par l'appel dedict
.dict
et remplacer__setitem__
pour générer une erreur? Également ajouter__hash__
de cours.def function(defaults=frozendict())
. Aussi thisngs comme algorithme de paramétrages, l'envoi dicts entre les composants du système, le multithreading, sans écluses. la canne à être bien et en toute sécurité fait avec frozendicts.frozendict
il y a projet. C'est la version deFrozenDict
mis en oeuvre avec l'aide de Cython.Curieusement, bien que nous ayons la rarement utile
frozenset
en python, il n'y a pas encore de gelée de cartographie. L'idée a été rejetée en PEP 416.De sorte que le python 2 solution:
Semble encore quelque peu boiteux:
En python3, vous avez la possibilité de cette:
Maintenant la configuration par défaut de l' peut être mis à jour dynamiquement, mais restent immuables où vous voulez qu'il soit immuable en passant à travers le proxy.
Ainsi, les changements dans la
default_config
sera mise à jourDEFAULTS
comme prévu, mais vous ne pouvez pas écrire à la configuration du proxy de l'objet lui-même.Certes, il n'est pas tout à fait la même chose comme un "immuable, hashable dict" - mais c'est un substitut décent donné le même genre de cas d'utilisation pour lesquels on peut vouloir un frozendict.
def foo(config=MappingProxyType({'a': 1})):
? Votre exemple permet encore de modification globale par le biais dedefault_config
, trop.config = default_config = {'a': 1}
est une faute de frappe.En supposant que les clés et les valeurs du dictionnaire sont eux-mêmes immuables (par exemple des chaînes de caractères) puis:
tuple(sorted(d.iteritems()))
est plus agréable.dict(t)
Il n'y a pas de
fronzedict
, mais vous pouvez utiliserMappingProxyType
qui a été ajouté à la bibliothèque standard de Python 3.3:Voici le code que j'ai utilisé. Je sous-classé frozenset. Les avantages sont les suivants.
Mise à jour Jan 21 2015: Le morceau de code que j'ai posté en 2014 utilisé une boucle for pour trouver une clé de correspondance. C'était incroyablement lent. Maintenant j'ai mis en place une application qui tire profit de frozenset de fonctions de hachage. Les paires clé-valeur sont stockés dans des conteneurs spéciaux où la
__hash__
et__eq__
fonctions sont basées sur la clé uniquement. Ce code a aussi été officiellement unité testée, contrairement à ce que j'ai posté ici en août 2014.MIT de style de licence.
Item
à la valeur de hachage de la clé est un pur hack!diff(diff({key}))
est toujours linéaire en la taille de la FrozenDict, tandis que les dict temps d'accès est constante dans la moyenne des cas.Je pense frozendict chaque fois que j'écris une fonction comme ceci:
optional_dict_parm = optional_dict_parm or {}
types.MappingProxyType
({})
comme valeur par défaut pour l'argument.Vous pouvez utiliser
frozendict
deutilspie
paquet comme:Que par la document:
Oui, c'est ma deuxième réponse, mais c'est une approche complètement différente. La première mise en œuvre a été en pure python. Celui-ci est en Cython. Si vous savez comment les utiliser et de les compiler Cython modules, c'est tout aussi rapide que régulier d'un dictionnaire. Environ .04 à .06 micro-sec pour récupérer une valeur unique.
C'est le fichier "frozen_dict.custode"
Voici le fichier "setup.py"
Si vous avez Cython installé, enregistrez les deux fichiers ci-dessus dans le même répertoire. Déplacer vers le répertoire dans la ligne de commande.
Et vous devriez faire.
Le principal inconvénient de
namedtuple
est qu'il doit être spécifié avant de l'utiliser, donc c'est moins pratique pour un seul cas d'utilisation.Cependant, il existe une solution pratique qui peut être utilisée pour traiter de nombreux cas. Disons que vous voulez avoir un immuable équivalent de la suite dict:
Cela peut être émulé comme ceci:
Il est même possible d'écrire une fonction auxiliaire pour automatiser ce:
Bien sûr, cela ne fonctionne que pour les plats à dicts, mais il ne devrait pas être trop difficile à mettre en œuvre une version récursive.
getattr(fa, x)
au lieu defa[x]
, pas dekeys
méthode à vos bouts de doigt, et toutes les autres raisons, un mappage peut être souhaitable.Installer frozendict
L'utiliser!
Une autre option est le
MultiDictProxy
classe à partir de lamultidict
paquet.Sous-classement
dict
je vois ce modèle dans la nature (github) et je voulais le mentionner:
exemple d'utilisation:
Pros
get()
,keys()
,items()
(iteritems()
sur py2) et tous les goodies dedict
hors de la boîte, sans explicitement la mise en œuvre de leurdict
qui signifie que la performance (dict
est écrit en c en Disponible)isinstance(my_frozen_dict, dict)
retourne True - bien que python encourage en tapant duck beaucoup de paquets utiliseisinstance()
, cela peut sauver de nombreuses modifications et personnalisationsContre
__hash__
un peu plus vite.En l'absence de la langue native de l'aide, vous pouvez soit le faire vous-même ou utiliser une solution existante. Heureusement Python rend simple pour étendre hors de leur base implémentations.
J'avais besoin de l'accès fixe les clés pour quelque chose à un moment, pour quelque chose qui était une sorte de monde-constanty genre de chose et que j'ai réglé sur quelque chose comme ceci:
L'utiliser comme
AVERTISSEMENT: je ne le recommande pas, pour la plupart des cas d'utilisation qu'il fait de certains assez graves compromis.