我正在构建一个非常大的字典,我正在执行许多检查以查看密钥是否在结构中,然后添加它是否唯一,或者如果它是相同的则递增计数器。
Python使用hash data structure来存储字典(不要与加密哈希函数混淆)。查找是O(1),但如果哈希表已满,则必须重新进行,这非常昂贵。
我的问题是,我会更好地使用AVL Binary Search Tree或哈希表是否足够好?
答案 0 :(得分:24)
唯一可以确定的方法是实现和检查,但我的猜测是字典会更快,因为二进制搜索树的查找和插入成本为O(log(n)),而我我认为除了最多的情况(例如大规模哈希冲突)之外,哈希表的O(1)查找将超过偶尔的大小调整。
如果您查看Python dictionary implementation,您会看到:
PyDict_MINSIZE
); (“NOTES ON OPTIMIZING DICTIONARIES”也值得一读。)
因此,如果您的词典有1,000,000个条目,我相信它会被调整大小十一次(8→32→128→512→2048→8192→32768→131072→262144→524288→1048576→2097152),费用为2,009,768调整大小期间的额外插入。这似乎远远低于将1,000,000次插入到AVL树中所涉及的所有重新平衡的成本。
答案 1 :(得分:4)
商品与独特商品的比例是多少? 预期的独特商品数量是多少?
如果哈希桶填满,那么扩展应该只是一些内存重新分配,而不是重新分配。
测试计数字典应该非常快速和容易。
另请注意自python 2.7以来可用的计数器类 http://docs.python.org/library/collections.html#counter-objects http://svn.python.org/view?view=rev&revision=68559
答案 2 :(得分:4)
Python词典经过高度优化。 Python进行了各种特殊情况的优化,Python开发人员在CPython字典实现中提供了这些优化。
“Beautiful Code”一书讨论了这一切。
第十八章是Python的字典实现:由Adrew Kuchling为所有人提供的所有东西
使用它比尝试实现手工制作的自定义实现要好得多,后者必须将所有这些优化复制到任何接近主要CPython字典查找实现的位置。
答案 3 :(得分:2)
您必须在C中实现自己的数据结构才能有合理的机会击败内置结构。
此外,您可以使用get
来避免一些开销,避免两次查找现有元素。
或者collections.Counter,如果你使用的是python 2.7 +。
def increment(map, key):
map[key] = map.get(key,0)+1
答案 4 :(得分:2)
使用dict是O(1)。随着dict的增长,有时需要重新分配,但这是分摊的O(1)
如果你的其他算法是O(log n),那么当数据集变大时,简单的dict将总是击败它。
如果你使用任何类型的树,我希望在那里有一个O(log n)组件。
哈希表不仅足够好,而且更好