2017-05-18 2 views
-1

Es scheint, aus irgendeinem Grunde, dass ein dict keinen nicht-doppelten Schlüssel haben kann, die BitArray ist() ex .:Hashing Bitarray? Zählen

data = {} 
for _ in xrange(10): 
    ba = ...generate repeatable bitarrays ... 
    data[ba] = 1 

print ba 

{BitArray ('11011'): 1, BitArray (‘ 11011 '): 1, Bitarray (' 11011 '): 1, Bitarray (' 01111 '): 1, Bitarray (' 11110 '): 1, Bitarray (' 11110 '): 1, Bitarray (' 01111 '): 1 , BitArray ('01111'): 1, BitArray ('11110'): 1, BitArray ('11110'): 1}

Sie deutlich, dass die doppelte sehen können, werden als unterschiedliche Schlüssel (zB ersten beiden Elemente gespeichert) Das ist seltsam. Was könnte der Grund sein? Mein Ziel ist es einfach zu zählen, wie oft ein Bitmuster auftaucht, und natürlich sind Dict's perfekt dafür, aber es scheint, dass bitarray() aus irgendeinem Grund für den Hash-Algorithmus undurchsichtig ist. btw .. Ich muss bitarray() verwenden, weil ich 10000 Bits + Muster mache.

Jede andere Idee effizienter Art und Weise des Auftretens von Bit pattens des Zählens ..

+0

Sie nicht sinnvoll eine BitArray können als ein Diktatschlüssel Selbst wenn Sie versuchen, einen TypeError auszulösen, hat die Klasse einen Fehler, bei dem sie den standardmäßigen identitätsbasierten Hash erbt, anstatt PyHash_NotImplemented zu verwenden. – user2357112

Antwort

-1

ich es gelöst:

desc = bitarray(res).to01() 
if desc in data : data[desc] += 1 
else : data[desc] = 1 

Gosh Ich vermisse Perl no-nonsense autovivification :)

+0

'.tobytes()' würde ein viel kompakteres Objekt erzeugen, das für die Verwendung als Wörterbuchschlüssel geeignet ist. Und ein 'collections.Counter' wäre in dieser Situation viel einfacher zu benutzen als ein rohes Wörterbuch. – jasonharper

1

diese Antwort Adressen Ihre erste Verwechslung in Bezug auf doppelte Wörterbuchschlüssel und ich nehme an, Sie beziehen sich auf bitarray() von bitarray Modul, * Ich habe dieses Modul nicht selbst verwendet.

oben In Ihrem Beispiel sind Sie nicht wirklich doppelten Dictionary-Schlüssel bekommen, könnte man sich auf diese Weise sehen, aber sie sind Duplikate nur mit dem bloßen Auge, zum Beispiel:

>>> class X: 
...  def __repr__(self): 
...    return '"X obj"' 
... 
>>> x1 = X() 
>>> x2 = X() 
>>> d = {x1:1, x2:2} 
>>> d 
{"X obj": 2, "X obj": 1} 

Aber x1 isn ‚t entspricht genau zu x2 und daher sind sie nicht dupliziert, sie sind verschiedene Objekte der Klasse X:

>>> x1 == x2 
False 
>>> #same as 
... id(x1) == id(x2) 
False 
>>> #same as 
...x1 is x2 
False 

da darüber hinaus X Klasse __repr__ definiert, die th zurück Die String-Repräsentation für ihre Objekte, Sie würden denken, das Wörterbuch d hat doppelte Schlüssel, wieder gibt es keine doppelten Schlüssel noch sind die Schlüssel des Typs str; Schlüssel Wert 1 ist X Objekt und Schlüssel-Wert 2 ist ein weiteres Ziel der X - buchstäblich zwei verschiedene Objekte mit einer einzigen String-Darstellung durch ihre Klasse __repr__ Methode zurückgegeben:

>>> # keys are instance of X not strings 
... d 
{"X obj": 2, "X obj": 1}  
>>> d["X obj"] 
KeyError: 'X obj' 
>>>[x1] 
1 
>>>[x2] 
2