似乎由于某种原因,dict不能有一个非重复的键,这是bitarray() 例如:
data = {}
for _ in xrange(10):
ba = ...generate repeatable bitarrays ...
data[ba] = 1
print ba
{bitarray(' 11011'):1,bitarray(' 11011'):1,bitarray(' 11011'):1,bitarray(&# 39; 01111'):1,bitarray(' 11110'):1,bitarray(' 11110'):1,bitarray(' 01111'): 1,bitarray(' 01111'):1,bitarray(' 11110'):1,bitarray(' 11110'):1}
您可以清楚地看到副本存储为不同的键(例如前两个元素)!!这很奇怪。可能是什么原因。 我的目标只是计算一个模式显示的次数,当然Dict是完美的,但似乎bitarray()由于某种原因对散列算法是不透明的。 顺便说一句..我必须使用bitarray(),因为我做10000比特+模式。
计算位模式发生的有效方法的任何其他想法..
答案 0 :(得分:1)
这个答案解决了你对重复字典键的第一次困惑,我假设你是指bitarray模块中的bitarray()
,*我自己没有使用过这个模块。
在上面的示例中,您实际上并没有获得重复的字典键,您可能会看到它们,但它们只是肉眼复制,例如:
>>> class X:
... def __repr__(self):
... return '"X obj"'
...
>>> x1 = X()
>>> x2 = X()
>>> d = {x1:1, x2:2}
>>> d
{"X obj": 2, "X obj": 1}
但是x1
并不完全等于x2
,因此它们不是重复的,它们是类X
的不同对象:
>>> x1 == x2
False
>>> #same as
... id(x1) == id(x2)
False
>>> #same as
...x1 is x2
False
此外,因为X
类定义__repr__
返回其对象的字符串表示形式,您会认为字典d
具有重复键,同样没有重复键也没有键类型str
;值1的键是X
对象,值2的键是X
的另一个对象 - 实际上是两个不同的对象,它们的类__repr__
方法返回一个字符串表示:
>>> # keys are instance of X not strings
... d
{"X obj": 2, "X obj": 1}
>>> d["X obj"]
KeyError: 'X obj'
>>>[x1]
1
>>>[x2]
2
答案 1 :(得分:1)
直到BitArray 0.8.1
(或更高版本)我认为它不满足哈希不变属性。
要解决此问题,您应该将位数组转换为byte
格式,如下所示。
>>> from bitarray import bitarray
>>> l = [bitarray('11111'), bitarray('11111'), bitarray('11010'), bitarray('11110'), bitarray('11111'), bitarray('11010')]
>>> for x in l: ht[x.tobytes()] = 0
...
>>> for x in l: ht[x.tobytes()] += 1
...
>>> ht
{'\xf8': 3, '\xf0': 1, '\xd0': 2}
请记住,您可以使用bitarray
命令从byte
格式取回frombytes(byte)
。但是,在这种情况下,您必须明确跟踪bitarray
的大小,因为它将返回大小为8的bitarray
。
如果您想将bitarray
保留在词典中:
>>> from bitarray import bitarray
>>> l = [bitarray('11111'), bitarray('11111'), bitarray('11010'), bitarray('11110'), bitarray('11111'), bitarray('11010')]
>>> ht = {}
>>> for x in l: ht[x.tobytes()] = (0, x)
...
>>> for x in l:
... old_count = ht[x.tobytes()][0]
... ht[x.tobytes()] = (old_count+1, x)
...
>>> ht
{'\xf8': (3, bitarray('11111')), '\xf0': (1, bitarray('11110')), '\xd0': (2, bitarray('11010'))}
>>> for x,y in ht.iteritems(): print(y)
...
(3, bitarray('11111'))
(1, bitarray('11110'))
(2, bitarray('11010'))
答案 2 :(得分:-1)
我解决了它:
desc = bitarray(res).to01()
if desc in data : data[desc] += 1
else : data[desc] = 1
gosh我想念perl no-unsense autovivification :)