Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 哈希位数组?计数_Python_Dictionary_Counting_Bitarray - Fatal编程技术网

Python 哈希位数组?计数

Python 哈希位数组?计数,python,dictionary,counting,bitarray,Python,Dictionary,Counting,Bitarray,出于某种原因,dict不能有一个非重复的密钥,即bitarray() 例: {bitarray('11011'):1,bitarray('11011'):1,bitarray('11011'):1,bitarray('01111'):1,bitarray('11110'):1,bitarray('01111'):1,bitarray('11110'):1,bitarray('11110'):1,bitarray('11110'):1} 您可以清楚地看到,副本存储为不同的键(即前两个元素)!!这很

出于某种原因,dict不能有一个非重复的密钥,即bitarray() 例:

{bitarray('11011'):1,bitarray('11011'):1,bitarray('11011'):1,bitarray('01111'):1,bitarray('11110'):1,bitarray('01111'):1,bitarray('11110'):1,bitarray('11110'):1,bitarray('11110'):1}

您可以清楚地看到,副本存储为不同的键(即前两个元素)!!这很奇怪。原因可能是什么。 我的目标是简单地计算一个位模式出现的次数,当然Dict非常适合这样做,但是出于某种原因,bitarray()似乎对哈希算法是不透明的。 顺便提一下我必须使用bitarray(),因为我需要10000位+模式

关于计算位模式发生率的有效方法的任何其他想法

我解决了它:

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

天哪,我错过了perl无意义的自动激活:)

这个答案解决了您关于重复字典键的第一个困惑,我假设您指的是模块中的
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
类定义了返回其对象的字符串表示形式的
\uuuu repr\uuuu
,因此您可能会认为dictionary
d
具有重复的键,同样没有重复的键,也没有类型为
str
的键;值1的键是
X
对象,值2的键是
X
的另一个对象——实际上是两个不同的对象,它们的类的
\uuuuu repr\uuu
方法返回一个字符串表示:

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

直到
位数组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}
请记住,您可以使用命令
frombytes(byte)
byte
格式中获取
bitarray
。不过,在这种情况下,您必须明确跟踪
bitarray
的大小,因为它将返回大小为8倍的
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'))

.tobytes()
将生成一个更紧凑的对象,适合用作字典键。在这种情况下,
collections.Counter
比原始字典更容易使用。不能有意义地将位数组用作dict键。即使尝试也会引发TypeError,但是该类有一个bug,它继承了默认的基于身份的哈希,而不是使用PyHash。
>>> 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'))