什么是Python的哈希表/字典实现,不存储密钥?

时间:2009-12-16 23:06:21

标签: python dictionary map hashtable data-structures

我在哈希表中存储了数百万,可能是数十亿的4字节值,我不想存储任何密钥。我希望只需要存储键和值的哈希值。这必须很快并且都保存在RAM中。与set()不同,这些条目仍然会被密钥查找。

Python的这个实现是什么?这有名字吗?

是的,允许碰撞,可以忽略。

(我可以为碰撞做一个例外,可以存储密钥。或者,碰撞只能覆盖以前存储的值。)

10 个答案:

答案 0 :(得分:5)

Bloomier filters - 节省空间的关联数组

来自维基百科:

  

Chazelle等人。 (2004)设计了一个   Bloom过滤器的泛化   可以将值与每个值相关联   已插入的元素,   实现一个关联数组。   像Bloom过滤器一样,这些结构   通过以下方式实现小空间开销   接受虚假的小概率   阳性。在“Bloomier   过滤器“,定义了误报   当键是返回结果时   不在地图上。地图永远不会   为该键返回错误的值   在地图上。

答案 1 :(得分:3)

如何使用普通字典而不是:

d[x]=y

使用:

d[hash(x)]=y

要查找:

d[hash(foo)]

当然,如果存在哈希冲突,则可能会返回错误的值。

答案 2 :(得分:3)

它是一个很好的旧空间与运行时间的权衡:你可以拥有恒定的时间,线性空间用于hastable中的键。或者,您可以隐式存储密钥,并使用二叉​​树使用log n time。值的(二进制)哈希为您提供树中存储它的路径。

答案 3 :(得分:2)

在RAM中构建自己的b树。

内存使用:

(4字节)比较哈希值

(4个字节)下一个叶子的索引,如果散列< =比较或者如果是负值索引

(4字节)下一个叶子的索引,如果散列>比较OR或负值指数

b树的每个b树节点12个字节。值的开销更大(见下文)。

如何在Python中构建它 - 不存在32位整数的“本机数组”,几乎没有额外的内存开销......?他们叫什么......反正那些。

分隔有序的子数组,每个子数组包含一个或多个值。上面的“索引值”是这个大数组的索引,允许检索与哈希匹配的所有值。

这假定为32位散列。如果有,则每个b树节点需要更多字节 大于2 ^ 31-1个条目或更大的哈希。

但也许工作中的扳手:请注意,如果您没有存储键值,则无法验证查找的哈希值是否只对应于您的键,除非通过某种算法或组织机制保证没有两个键会有相同的哈希值。这里相当严重的问题。你考虑过吗? :)

答案 4 :(得分:2)

虽然python词典非常有效,但我认为如果您要存储数十亿个项目,您可能需要create您自己的C扩展,其数据结构已经过优化,你实际使用它的方式(顺序访问?完全随机?等)。

要创建C扩展程序,您可能需要使用SWIGPyrex之类的内容(我从未使用过)。

答案 5 :(得分:1)

哈希表必须存储密钥,除非你提供绝对没有冲突的哈希函数,这几乎是不可能的。

但是,如果你的键是字符串式的,那么就有一个非常节省空间的数据结构 - 有向无环字图(DAWG)。我不知道任何Python实现。

答案 6 :(得分:1)

这不是你要求购买为什么不考虑东京内阁或BerkleyDB这项工作?它不会在内存中,但是您可以通过性能来获得更大的存储容量。您仍然可以将列表保留在内存中,并仅使用数据库来检查是否存在。

答案 7 :(得分:1)

如果您实际存储了数百万个唯一值,为什么不使用字典呢? 商店:d[hash(key)/32] |= 2**(hash(key)%32)
检查:(d[hash(key)/32] | 2**(hash(key)%32))

如果您有数十亿条目,请使用大小为(2 ** 32)/ 32的numpy数组。 (因为,毕竟,你只有40亿个可能存储的值,无论如何)。

答案 8 :(得分:1)

请您告诉我们有关钥匙的更多信息?我想知道我们可以利用的密钥是否有任何规律性。

如果键是小字母表中的字符串(例如:数字字符串,如电话号码),则可以使用trie数据结构:

http://en.wikipedia.org/wiki/Trie

答案 9 :(得分:0)

为什么不是字典+ hashlib?

>>> import hashlib
>>> hashtable = {}
>>> def myHash(obj):
    return hashlib.sha224(obj).hexdigest()

>>> hashtable[myHash("foo")] = 'bar'
>>> hashtable
{'0808f64e60d58979fcb676c96ec938270dea42445aeefcd3a4e6f8db': 'bar'}