在Python中从dict弹出元素的时间复杂度是多少?

时间:2017-05-16 19:45:54

标签: python algorithm dictionary

这是一种组合问题。我有一个非常大的列表,SchedulingItem operator[](Schedule obj,int el){ return obj.OfVector().at(el); } - 存储所有可能的值 - 和一个非常大的all_possibledict,它存储所有实际存在的值,例如:

present

目前,我的搜索看起来有点像:

all_possible = [1, 2, 3, 4, 5]
present = {1: 'some_value', 3: 'some_other_value'}

这很好用,因为对于每次迭代,字典中只有一个查找,以及Python字典is O(1)的平均查找时间。

然而,摊销的最坏情况查找时间是O(N),并且由于字典可能如此庞大(数百万个元素),我所考虑的优化之一涉及在遍历时从字典中弹出元素(因此后续查找的搜索空间较小):

for key in all_possible:
    value = present.get(key, None)
    if value is None:
        do_something_if_key_not_present()
    else:
        do_something_if_key_is_present()

我的问题是字典for key in all_possible: value = present.pop(key, None) # this line changes, dict shrinks if value is None: do_something_if_key_not_present() else: do_something_if_key_is_present() 的时间复杂度是什么?我知道像pop这样的结构中的平均案例pop操作是O(N ),但我找不到任何可靠的文档来表示从list弹出的复杂性。如果它最终成为O(1),这可能会加速我的搜索,但如果它更高,我可能会伤害自己。

1 个答案:

答案 0 :(得分:10)

dict.pop的时间复杂度与dict.get的时间复杂度完全相同。 list.pop是O(N),因为它需要移动元素,但dict.pop不会这样做。

尽管如此,dict.pop可能无法改善您的查询时间。从dict中删除密钥需要在其位置留下DKIX_DUMMY标记,并且查找例程需要将它发现的任何DKIX_DUMMY视为哈希冲突,并继续进行。充其量,您将在已删除的密钥上保存一些==比较。

即使dict.pop是一项改进,也不会使您免于O(N)最坏情况的查找时间。如果你需要处理对抗键选择,那么dicts可能不适合你的用例。