【问题标题】:Does Python use linked lists for lists? Why is inserting slow?Python 是否使用链表作为列表?为什么插入慢?
【发布时间】:2012-08-29 17:41:54
【问题描述】:

刚刚学习 Python。阅读官方教程。我遇到了这个:

虽然从列表末尾追加和弹出很快,但从列表开头插入或弹出很慢(因为所有其他元素都必须移动一个)。

我已经猜到像 Python 这样成熟的语言会有各种各样的优化,那么为什么 Python [似乎] 不使用链表来快速插入呢?

【问题讨论】:

  • 你可以很简单地实现一个,如果你也想使用它,但它会减慢访问速度......
  • 每个数据结构都有它的取舍。 Python 选择了一个不是最适合插入的。
  • 查看this question 的答案以查看权衡。

标签: python


【解决方案1】:

Python 在内存中使用线性列表布局,因此索引 速度很快(O(1))。

【讨论】:

    【解决方案2】:

    正如 Greg Hewgill 已经指出的那样,python 列表使用连续的内存块来加快索引速度。如果您想要链表的性能特征,可以使用deque。但你最初的前提对我来说似乎有缺陷。向(标准)链表中间的索引插入也很慢。

    【讨论】:

    • 我应该澄清我的前提。意思是说,“......所以在开头的插入速度很快。”
    【解决方案3】:

    list 被实现为一个数组列表。如果要频繁插入,可以使用deque(但要注意遍历到中间的开销很大)。

    或者,您可以使用堆。如果您花时间查看文档,一切都在那里。

    【讨论】:

      【解决方案4】:

      Python 所称的“列表”实际上并不是链表。它们更像是数组。请参阅 Python 常见问题解答中的 list entry from the Python glossaryHow do you make an array in Python?

      【讨论】:

        【解决方案5】:

        Python 列表是使用可调整大小的对其他对象的引用数组来实现的。与链表实现的 O(n) 查找相比,这提供了 O(1) 查找。

        How are lists implemented?

        正如您所提到的,此实现使插入到 Python 列表的开头或中间的速度变慢,因为插入点右侧的数组中的每个元素都必须移动到一个元素上。此外,有时必须调整数组的大小以容纳更多元素。对于插入链表,您仍然需要 O(n) 时间来找到要插入的位置,但实际插入本身将是 O(1),因为您只需要立即更改节点中的引用在插入点之前和之后(假设是双向链表)。

        因此,让 Python 列表使用动态数组而不是链表的决定与语言实现的“成熟度”无关。在不同的数据结构之间存在简单的权衡,Python 的设计者认为动态数组是总体上最好的选择。他们可能认为索引列表比向列表中插入数据更常见,因此在这种情况下动态数组是更好的选择。

        有关各种数据结构性能特征的比较,请参阅动态数组维基百科文章中的下表:

        https://en.wikipedia.org/wiki/Dynamic_array#Performance

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-03-23
          • 2021-12-25
          • 2016-05-03
          • 2017-02-11
          • 2020-09-17
          • 2010-10-24
          • 1970-01-01
          相关资源
          最近更新 更多