这是一种组合问题。我有一个非常大的列表,SchedulingItem operator[](Schedule obj,int el){
return obj.OfVector().at(el);
}
- 存储所有可能的值 - 和一个非常大的all_possible
,dict
,它存储所有实际存在的值,例如:
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),这可能会加速我的搜索,但如果它更高,我可能会伤害自己。
答案 0 :(得分:10)
dict.pop
的时间复杂度与dict.get
的时间复杂度完全相同。 list.pop
是O(N),因为它需要移动元素,但dict.pop
不会这样做。
尽管如此,dict.pop
可能无法改善您的查询时间。从dict中删除密钥需要在其位置留下DKIX_DUMMY
标记,并且查找例程需要将它发现的任何DKIX_DUMMY
视为哈希冲突,并继续进行。充其量,您将在已删除的密钥上保存一些==
比较。
即使dict.pop
是一项改进,也不会使您免于O(N)最坏情况的查找时间。如果你需要处理对抗键选择,那么dicts可能不适合你的用例。