Python的字典哈希数据结构

时间:2010-11-25 17:00:49

标签: python algorithm performance data-structures

我正在构建一个非常大的字典,我正在执行许多检查以查看密钥是否在结构中,然后添加它是否唯一,或者如果它是相同的则递增计数器。

Python使用hash data structure来存储字典(不要与加密哈希函数混淆)。查找是O(1),但如果哈希表已满,则必须重新进行,这非常昂贵。

我的问题是,我会更好地使用AVL Binary Search Tree或哈希表是否足够好?

5 个答案:

答案 0 :(得分:24)

唯一可以确定的方法是实现和检查,但我的猜测是字典会更快,因为二进制搜索树的查找和插入成本为O(log(n)),而我我认为除了最多的情况(例如大规模哈希冲突)之外,哈希表的O(1)查找将超过偶尔的大小调整。

如果您查看Python dictionary implementation,您会看到:

  1. 字典以8个条目(PyDict_MINSIZE);
  2. 开头
  3. 一个字词,当它增长时,条目大小为50,000或更少的四倍;
  4. 超过50,000个词条的词典在增长时会翻倍;
  5. 键哈希缓存在字典中,因此在调整字典大小时不会重新计算它们。
  6. (“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字典实现中提供了这些优化。

  1. 在CPython中,所有PyDictObject都针对仅包含字符串键的字典进行了优化。
  2. Python的词典努力永远不会超过2 / 3rds。
  3. 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)组件。

哈希表不仅足够好,而且更好