L'un des types intégrés de Python est le dict.
>>> d = {"zero": False, "one": True}
>>> d["zero"]
False
>>> d["one"]
True
>>> type(d)
<class 'dict'>
Les dictionnaires sont des modules sans avoir à les utiliser explicitement dans le programme
>>> type(__builtins__.__dict__)
<class 'dict'>
>>> import os
>>> type(os.__dict__)
<class 'dict'>
Et attributs de classe
>>> class MyClass(object):
... def __init__(self):
... self.a = 1
...
>>> x = MyClass()
>>> x.__dict__
{'a': 1}
Il est utilisé implicitement à divers endroits.
Si vous le spécifiez comme clé de dictionnaire, une erreur peut se produire. Par exemple
>>> a = dict()
>>> type(a)
<class 'dict'>
>>> a[[0]] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
Si vous essayez d'utiliser une liste comme clé de dictionnaire comme celle-ci, vous vous fâcherez parce que c'est un type insaisissable. Voyons pourquoi il existe de telles restrictions.
https://ja.wikipedia.org/wiki/ハッシュ関数
Fonction de hachage(Fonction de hachage)Ou qu'est-ce qu'une fonction de résumé?
Une opération pour obtenir une valeur numérique représentant les données à partir de certaines données, ou
Une fonction pour obtenir une telle valeur numérique.
La signification de «représenter des données» est que la valeur obtenue par la fonction de hachage est
a == b (a.__eq__(b) == True)Puis hash(a) == hash(b) (a.__hash__() == b.__hash__())
Qu'il rencontre.
Dans le dictionnaire, les fonctions de hachage sont utilisées pour répondre à la demande de traitement à faible coût, en évitant toute la recherche par `` eq '' lors de la définition et de la récupération des valeurs.
eq``` → Ajouter une nouvelle clé
eq``` → erreurDans l'implémentation de CPython dict,
eq → Évitez le coût de` `` __eq__
Il a été conçu.
__hash__
Est-ce hashable tant qu'il y a une méthode? Selon la documentation
http://docs.python.jp/2.7/glossary.html#term-hashable
Un objet hachable a une valeur de hachage qui ne change pas pour le reste de sa vie.(__hash__()Besoin d'une méthode)、...
Et il est nécessaire que la valeur de hachage ne change pas pendant la durée de vie. Cependant, ce n'est généralement pas possible, de sorte que l'implémentation du paramètre de valeur de dictionnaire vérifie uniquement si la fonction de hachage peut être appelée.
La classification des objets intégrés est
Cependant, ce qui est inclus ici dans hashable est garanti que la valeur de hachage ne change pas pendant la durée de vie. Mais qu'en est-il des objets définis par l'utilisateur?
http://docs.python.jp/2.7/reference/datamodel.html#object.hash
La classe définit des objets modifiables__cmp__()Ou__eq__()Méthode
S'il est mis en œuvre,__hash__()Ne doit pas être défini. Ceci est un hachage dans l'implémentation du dictionnaire
Parce que la valeur doit être immuable.(Lorsque la valeur de hachage de l'objet change
Seau de hachage avec la mauvaise clé:Ce sera dans le seau de hachage)。
Essayons un exemple qui contourne en fait la vérification du type de clé. Dans l'exemple ci-dessous, UnhashableInFact a une fonction de hachage, mais la valeur de hachage change pendant la durée de vie de l'instance.
wrong_bucket.py
# -*- coding: utf-8 -*-
class UnhashableInFact(object):
def __init__(self, n):
self.n = n
def __hash__(self):
return hash(self.n)
def __eq__(self, other):
return self.n == other.n
if __name__ == '__main__':
a = UnhashableInFact(1)
b = UnhashableInFact(2)
mydict = {a: "value for 1", b: "value for 2"}
print(mydict[a], mydict[b]) # (1)
a.n = 2 #→ Changements de valeur de hachage
print(mydict[a], mydict[b]) # (2)
c = UnhashableInFact(1)
print(c in mydict) # (3)
Quand ceci est exécuté, le comportement est le suivant.
% python wrong_bucket.py
('value for 1', 'value for 2') # (1)Vous pouvez récupérer la valeur de chaque compartiment
('value for 2', 'value for 2') # (2)Tous les deux"value for 2"Va sortir
False # (3)Même si vous apportez quelque chose d'égal à la clé d'origine"value for 1"Ne peut pas être retiré
Pourquoi s'est-il comporté ainsi? L'entrée du dictionnaire est
cpython/Include/dictobject.h
typedef struct {
/* Cached hash code of me_key. Note that hash codes are C longs.
* We have to use Py_ssize_t instead because dict_popitem() abuses
* me_hash to hold a search finger.
*/
Py_ssize_t me_hash;
PyObject *me_key;
PyObject *me_value;
} PyDictEntry;
Il est devenu
http://docs.python.jp/2.7/reference/datamodel.html#object.hash
De la classe des parents__hash__()Hériter de la méthode,__cmp__()Ou__eq__()Sens de
En changeant(Par exemple, passer d'une équivalence basée sur la valeur à une équivalence basée sur l'identité)
Puisque la valeur de hachage de la classe n'est plus valide__hash__ =N'écrire aucun dans la définition de classe
Vous pouvez déclarer explicitement qu'il n'est pas hachable.
Essayons.
unhashable.py
class Unhashable(object):
__hash__ = None
def __init__(self, n):
self.n = n
def __eq__(self, other):
return self.n == other.n
if __name__ == '__main__':
a = Unhashable(1)
{a: "value for 1"}
De cette façon, vous pouvez le lire lorsque vous l'utilisez comme clé de dictionnaire:
% python unhashable.py
Traceback (most recent call last):
File "unhashable.py", line 13, in <module>
{a: "value for 1"}
TypeError: unhashable type: 'Unhashable'
Dans Python3, remplacer `` eq``` le définira automatiquement sur Aucun.
http://docs.python.jp/3/reference/datamodel.html#object.hash
__eq__()Primordial__hash__()Les classes qui ne définissent pas sont implicites
A été défini sur Aucun__hash__()Avoir. classe__hash__()La méthode est
Si aucun, il est approprié d'essayer d'obtenir la valeur de hachage d'une instance de cette classe
TypeError est levé et est une instance(obj, collections.Hashable)vérifier
Ensuite, il sera correctement reconnu comme non hachable.
http://docs.python.jp/2.7/glossary.html#term-immutable
Un objet avec une valeur fixe. Les objets immuables incluent des nombres, des chaînes,
Et tuples et ainsi de suite. Les valeurs de ces objets ne peuvent pas être modifiées. Une autre valeur
Vous devez créer un nouvel objet à retenir.
Les objets immuables jouent un rôle important dans les situations où des valeurs de hachage fixes sont requises.
Un exemple est une clé dans un dictionnaire.
Les clés dans les dictionnaires sont mentionnées comme une utilisation d'immuable.
Recommended Posts