8
votes

Python: détecter les doublons en utilisant un ensemble

J'ai un grand nombre d'objets que je dois stocker en mémoire pour le traitement de Python. Plus précisément, j'essaie d'éliminer les doublons d'un grand ensemble d'objets. Je tiens à considérer deux objets "égaux" si une certaine variable d'instance dans l'objet est égale. Donc, j'ai supposé que le moyen le plus simple de le faire serait d'insérer tous mes objets dans un ensemble et de remplacer la méthode __ de hachage __ de sorte qu'il heurte la variable d'instance dont je suis concerné.

, en tant que test, j'ai essayé ce qui suit: xxx

ici, je définis une classe personne et deux instances de personne avec le même nom La variable doit être égal, quelle que soit la valeur de toute autre variable d'instance. Malheureusement, ces sorties: xxx

Notez que foo apparaît deux fois, ce programme n'a donc pas remarqué des doublons. Pourtant, l'expression hachage (personne ("foo", 10)) == hachage (personne ("foo", 1000)) est vrai . Alors, pourquoi cela ne détecte-t-il pas correctement les objets personne ?


0 commentaires

5 Réponses :


12
votes

Vous avez oublié de aussi Définir __ eq __ () .

Si une classe ne définit pas un __ cmp __ () ou __ eq __ () méthode Il ne faut pas définir un __ hachage __ () Opération; S'il définit __ cmp __ () ou __ eq __ () mais pas __ hachage __ () , ses instances ne seront pas utilisables dans des collections hachées. Si une classe définit des objets mutables et implémente un __ cmP __ () ou __ eq __ () méthode, il ne doit pas implémenter __ hachage __ () , depuis la collecte de hachable Les implémentations exigent que la valeur de hachage d'un objet soit immuable (si la valeur de hachage de l'objet change, il sera dans le mauvais godet de hachage).


1 commentaires

L'explication est due: l'ensemble considère les objets égaux si o1 == o2 . La fonction de hachage n'est utilisée que pour étaller les objets sur les godets de la table de hachage, alors seuls les objets avec le même hachage (qui se retrouvent dans le même godet) doivent être comparés à l'égalité. Ainsi, pour dict et définir pour fonctionner la fonction de hachage doit satisfaire la condition x == y => hachage (x) == hachage (Y) , mais l'oposite ( hachage (x) == hachage (y) => x == y ) n'est jamais vrai.



2
votes

La fonction de hachage ne suffit pas à distinguer l'objet que vous devez implémenter la fonction de comparaison (c'est-à-dire. __ eq __ ).


0 commentaires

4
votes

Un ensemble devra évidemment faire face aux collisions de hachage. Si le hachage de deux objets correspond, l'ensemble les comparera à l'aide de l'opérateur == pour vous assurer qu'ils sont vraiment égaux. Dans votre cas, cela ne produira que true si les deux objets sont le même objet (la mise en œuvre standard pour les classes définies par l'utilisateur).

histoire longue courte: définissez également __ eq __ () pour le faire fonctionner.


0 commentaires

0
votes

Vous avez également besoin de la méthode __ EQ __ ().


0 commentaires

1
votes

une fonction de hachage dit efficacement "A peut-être égale à B" ou "A non égal à B (à coup sûr)".

S'il est dit "peut-être égale" puis l'égalité doit être vérifiée de toute façon pour s'assurer, c'est pourquoi Vous devez également implémenter __ eq __ .

Néanmoins, définissant __ hachage __ vécu de manière significative les choses en faisant de manière significative en faisant "un B (non égal à B (à certitude)" un o (1) opération.

La fonction de hachage doit toutefois toujours suivre la "règle de hachage":

  • "Règle de hachage": Les choses égales doivent hacher à la même valeur
  • (Justification: sinon nous dirions "un non égal à B (à coup sûr)" quand ce n'est pas le cas)

    Par exemple, vous pouvez tout hash tout par def __hash __ (auto): retour 1 . Cela serait toujours correct, mais il serait inefficace car vous devriez vérifier __ eq __ à chaque fois, ce qui peut être un processus long si vous avez des structures de données importantes compliquées (par exemple avec de grandes listes, des dictionnaires, des dictionnaires, etc Si Bob est une personne de 20 ans et que Bob est une autre personne de 30 ans et sont des personnes différentes (probablement à moins que ce soit une sorte de maintien de la piste-de-peu-la-personne - du programme à l'origine), puis Ils seront hachés à la même valeur et doivent être comparés à __ eq __ . C'est parfaitement bien, mais je l'implémenterais comme: xxx

    Notez que votre chemin est toujours correct. Il aurait cependant été une erreur de codage à utiliser hachage ((auto.name, self.action)) dans un monde où personne ("bob", âge = 20) et personne ("bob", âge = 30) était en fait la même personne, car la fonction de hachage indiquerait qu'ils sont différentes, tandis que la fonction égale ne serait pas (mais être ignorée).


0 commentaires