Python是否使用列表的链接列表?为什么插入慢?

时间:2012-09-05 03:20:19

标签: python

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

  

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

我猜想像Python这样的成熟语言会有各种各样的优化,那么为什么Python [似乎]不使用链接列表以便插入速度快?

5 个答案:

答案 0 :(得分:19)

Python在内存中使用线性列表布局,以便索引快(O(1))。

答案 1 :(得分:8)

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

答案 2 :(得分:3)

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

答案 3 :(得分:2)

list是作为一个arraylist实现的。如果要频繁插入,可以使用deque(但请注意,遍历中间位置的费用很高)。

或者,您可以使用堆。如果您花时间查看文档,那就完全可以了。

答案 4 :(得分:2)

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

请参阅How are lists implemented?

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

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

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

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