8
votes

Python 2: Signification différente du mot-clé "dans" pour les ensembles et listes

considérer cet extrait: xxx

qui évalue à: xxx

peut-on expliquer pourquoi le mot clé "IN 'a une signification différente Pour les ensembles et les listes? Je m'aurais attendu à la fois de retourner vrai, en particulier lorsque le type à tester a des méthodes d'égalité définies.


3 Réponses :


16
votes

Le sens est le même, mais la mise en œuvre est différente. Les listes examinent simplement chaque objet, vérifiant l'égalité, de sorte que cela fonctionne pour votre classe. Définit d'abord le hasch les objets et s'ils ne mettent pas en œuvre correctement le hasch, l'ensemble ne semble pas fonctionner.

Votre classe définit __ eq __ , mais ne définit pas __ hachage __ , et donc ne fonctionnera pas correctement pour les ensembles ou les clés de dictionnaires. La règle de __ eq __ et __ hachage __ est que deux objets que __ eq __ comme vrai doivent également avoir des haubes égales. Par défaut, objets hachage basés sur leur adresse mémoire. Donc, vos deux objets égaux par votre définition ne fournissent pas le même hachage, ils brisent la règle sur __ eq __ et __ hachage __ .

si Vous fournissez un __ hachage __ , cela fonctionnera bien. Pour votre code d'échantillon, cela pourrait être: xxx


2 commentaires

C'est l'une des choses que Python 3 traite plus clairement: il refusera de définir un objet de tout objet qui n'a pas de __ hachage __ () . Python 2 a une référence par défaut __ hachage __ () qui reflète l'identité de l'objet plutôt que l'égalité.


En réalité, ce qui s'est passé est que les classes classiques se sont comportées de la même manière (ne définissant pas une méthode __ de hash __ vous donneraient une valeur par défaut qui a soulevé un typeError si vous avez défini __ cmp __ __ EQ __ ,) Mais ensuite des classes de style neuf ont été introduites (en Python 2.2) et que ce comportement n'était pas correctement copié. Cette supervision a été manquée pour suffisamment de communiqués qui changeaient potentiellement une pause potentiellement trop de code, la fixation que celle-ci a été retardée jusqu'à python 3.




3
votes

Dans presque toute la mise en œuvre de la haquetable, y compris Python, si vous remplacez la méthode d'égalité, vous devez remplacer la méthode de hachage (en python, c'est __ hash __ ). L'opérateur dans pour les listes vérifie simplement l'égalité avec chaque élément de la liste, que l'opérateur in pour définit d'abord l'objet que vous recherchez, vérifie un objet dans ce Slot de la haquetable, puis vérifie l'égalité s'il y a quelque chose dans la fente. Donc, si vous remplacez __ eq __ sans remplacer __ hachage __ , vous ne pouvez pas garantir que l'opérateur in pour les ensembles vérifiera dans le bon emplacement.


0 commentaires