0
votes

Comment avoir des objets différents de différentes classes dans un dict en python?

J'ai eu une question sur les dictionnaires avec des objets personnalisés. Dans un dict, je sais que la clé doit être immuable, donc si je veux utiliser une classe personnalisée, je dois définir sa fonction de hachage. Le docteur Hash Doc en Python vous recommande d'utiliser la fonction de hachage sur le tuple de la méthode Equal Dunder. Donc, par exemple, j'ai défini la température de la classe personnalisée en tant que telle: xxx pré>

de cette façon, je peux avoir une clé: une paire de valeur telle que TEMP (1): 1. Donc, à ma question. En Python, vous pouvez avoir des types différents dans le même dict. Donc, j'ai déclaré ce dict: p>

myDict={ temp(1):1, temp(2):2, 'a':1,1:1, (1,2):1, True:1 }


0 commentaires

3 Réponses :


2
votes

Votre méthode EQ doit vérifier si l'autre objet est le même type: xxx

qui dit, je vous recommande fortement d'utiliser Dataclasses pour des cas comme celui-ci. Ils définissent init, eq et (si gelen = true ) hachage pour vous, ce qui aide à éviter ce genre de problème.


2 commentaires

Du code disponible et l'explication donnée, il semble que TEMP est censé fonctionner comme une enveloppe de valeurs génériques, ce qui signifie que vous ne voulez pas nécessairement comparer avec uniquement des objets de la même classe. La meilleure option changerait probablement le renvoi notamplementé sur renvoyer auto.value == autre . De cette façon, la classe est capable de comparer avec d'autres valeurs et avec elle-même.


Merci pour votre réponse. Question rapide, devrais-je modifier la méthode LT pour prendre en compte le fait d'être une instance ou non? En outre, pourquoi avez-vous changé votre code de l'original `` `renvoyé isinstance (Autres, Temp) et Self.Value == Autres.Value` `` J'ai compris pourquoi vous avez retourné ce code, mais je ne vois pas pourquoi le besoin pour le changement. Y a-t-il eu un problème avec votre code d'origine?



1
votes

Le problème se produit lors de l'exécution du __ eq __ code> et __ lt __ code> Méthodes de Dunder. Vous pouvez reproduire la même chose en exécutant: xxx pré>

Le problème se produit car __ eq __ code> reçoit autre code> comme 1, et la valeur 1 n'a pas Un .value code>, mais vous essayez de l'utiliser ici: p> xxx pré>

Si vous utilisez simplement d'autres comparaisons, cela devrait fonctionner: P >

class temp():
    def __init__(self,value):
        self.value = value
    def __hash__(self):
        return hash(self.value)
    def __eq__(self,other):
        return self.value == other
    def __lt__(self,other):
        return self.value < other


1 commentaires

Merci pour l'explication! Maintenant, je sais comment le hash & égal vient de jouer. Juste pour mentionner, le code que vous avez fourni ne fonctionne pas car la comparaison donnerait des erreurs et traite certains objets de la même manière quand ils ne le sont pas. Par exemple, la dict: `` `x = {bob (1): 1,2: 2}` `` `Bob (2) sera évalué à vrai lorsque je voudrais / penser qu'elle évaluera à la fausse. Pour résoudre ce problème, je comparais toujours l'attribut de valeur, mais aussi vérifier qu'ils sont le même type.



1
votes

Vous pouvez définir votre méthode __ __ __ comme ceci: xxx

assez étrangement dans mes tests, j'ai trouvé que si la clé est un tuple ou un flotteur, cela fonctionne bien.

Quant à la deuxième question, cela a à voir avec la manière dont un dict fonctionne. Pour chaque clé, l'instance de dict vérifie si le hachage de la clé existe. Si oui, alors il vérifie l'égalité avec d'autres clés avec le même hachage. Ici, la vérification de l'égalité est de vérifier si elles sont fondamentalement les mêmes clés (et donc le même hachage). Si la vérification de l'égalité échoue, les touches sont jugées différentes.

S'il n'y a pas de collision de hachage, aucun contrôle d'égalité n'est effectué. Par conséquent, lorsque vous avez utilisé un tuple comme une clé, dites, (1, 2) , son hachage ((1, 2)) = 3713081631934410656 , qui n'existe pas encore dans le dict . Par conséquent, pas d'erreur.


2 commentaires

Devrais-je aussi comparer le type de classe dans la méthode LT aussi?


@UN B. Dans votre exemple de dict , il n'est pas nécessaire. Lorsque vous effectuez quelque chose comme le tri, ces méthodes de comparaison sont utilisées. Vous pouvez définitivement lancer une exception lorsque différentes classes sont comparées. Bien qu'il soit logique de dire que deux cas de classes dissemblables sont toujours inégales, vous ne voudrez peut-être jamais comparer << / code>, > , <= , ' > = `pour eux.