【问题标题】:Time Complexity of finding the first item in a dictionary in Python 3.7+在 Python 3.7+ 中查找字典中第一项的时间复杂度
【发布时间】:2020-08-12 01:21:53
【问题描述】:

自 Python 3.7 起,字典根据插入保留顺序。

您似乎可以使用next(iter(my_dict)) 获取字典中的第一项?

我的问题是关于该操作的大 O 时间复杂度?

我可以将next(iter(my_dict)) 视为常数时间(O(1))操作吗?或者在恒定时间内检索字典中第一项的最佳方法是什么?

我问的原因是我希望将它用于编码面试,其中非常强调解决方案的时间复杂度,而不是它以毫秒为单位的运行速度。

【问题讨论】:

  • @rdas 从 Python 3.7 开始,它不再只是一个实现细节。字典顺序保证按插入顺序排列,这是一种语言功能。 docs.python.org/3.7/library/stdtypes.html#mapping-types-dict 我认为使用有序字典是在面试中使用的有效数据结构?没有?
  • 看这与我的问题无关。在算法编码面试中,您通常会提出几种解决方案(并讨论权衡),因此我想使用 Python 3.7+ 的有序字典作为我的解决方案之一。因此,我想知道如何获得恒定时间复杂度的第一个元素。这不是我要向面试官提出的唯一解决方案,因此“这是否是我的面试官正在寻找的答案”的问题是无关紧要的。

标签: python python-3.x dictionary data-structures python-3.7


【解决方案1】:

这可能是最好的方法(实际上你现在得到了第一个密钥,next(iter(d.values())) 得到了你的价值)。

此操作(至少对组合表通过keysvaluesitems 进行任何迭代)iterates 通过包含dictionary entries 的数组:

PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i];
while (i < n && entry_ptr->me_value == NULL) {
    entry_ptr++;
    i++;
}

entry_ptr-&gt;me_value 保存每个相应键的值。

如果您的字典是新创建的,则会在第一次迭代期间找到第一个插入的项目(字典条目数组是仅追加的,因此保留顺序)。

如果您的字典已被更改(您已经删除了许多项目),在更糟糕的情况下,这可能会导致 O(N) 找到第一个(在剩余项目中)插入的项目(其中 N 是总数原始项目的数量)。这是因为在删除项目时字典没有调整大小,因此entry_ptr-&gt;me_value 对于许多条目来说是NULL

请注意,这是特定于 CPython 的。我不知道 Python 的其他实现如何实现这一点。

【讨论】:

    猜你喜欢
    • 2018-03-03
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-24
    相关资源
    最近更新 更多