2015-04-19 1 views
1

Quelle est la meilleure façon de générer un ensemble d'objets de type bitarray afin de pouvoir tester efficacement l'appartenance. La façon naïve ne semble pas fonctionner comme je le pense:Jeu de bitarray Python

>>> from bitarray import bitarray 
>>> 
>>> bitarray_set = set([bitarray('0000'), bitarray('0001')]) 
>>> bitarray_set 
set([bitarray('0001'), bitarray('0000')]) 
>>> 
>>> bitarray('0000') in bitarray_set 
False 

Une solution est de garder un ensemble distinct de chaînes ou un autre objet plus convivial que les clés. Convertissez ensuite un bitarray en chaîne et testez l'appartenance à cet ensemble à la place. Mais cela semble un peu lourd. Y a-t-il une meilleure solution?

Répondre

5

Il semble que bitarray ne maintient pas l'invariant de hachage:

>>> x = bitarray(b'0000') 
>>> y = bitarray(b'0000') 
>>> x == y 
True 
>>> hash(x) == hash(y) 
False 

Ceci est une violation de l'API pour __hash__, comme documented:

La seule propriété requise est que les objets qui comparent égaux ont la même valeur de hachage

Cela signifie que bitarrays sont effet facilement indémontable et ne fonctionnera pas de manière fiable dans les ensembles ou en tant que clés de dictionnaire.

Je considérerais cela comme un bogue dans la bibliothèque de bitarray. Je n'avais jamais entendu parler de bitarray auparavant, et il ne semble pas y avoir beaucoup de documentation. Pour autant que je puisse voir, cela ne dit même pas comment l'égalité est censée être définie pour les bitras, ni si elle est censée être gérable, mais il semble qu'elle implémente l'égalité et le hachage de manière incompatible.

+1

Je pense que vous avez raison à propos du problème, mais puisque les tableaux sont mutables, ils ne sont probablement pas censés être lavables, et nous devrions avoir 'bitarray .__ hash__ = None' pour l'empêcher. – DSM

+0

@DSM: Oui, cela aurait du sens. Comme je l'ai dit, la documentation n'indique pas clairement ce que le comportement est supposé être. Mais ils doivent soit devenir immuables ou non. – BrenBarn