为什么Python不';是否没有本机链表实现?

为什么Python不';是否没有本机链表实现?,python,arrays,algorithm,linked-list,Python,Arrays,Algorithm,Linked List,我尝试了一些快速的实验,比较了本地Python列表与链接列表实现(例如)的性能 本机python列表在不应该的情况下总是比非本机链表更快(根据理论) 我在上述测试中得到的结果如下: 本机链表=2.00000000001e-05 python列表=0.005576 非本地链接列表=3.9000000001E-05 所以,我想知道为什么Python没有本地链表数据结构。 在Python的例子中,在我看来,从算法上讲,拥有 链表而不是标准列表,以加快标准库的某些方面 我的理解是,列表数据结构是该语

我尝试了一些快速的实验,比较了本地Python列表与链接列表实现(例如)的性能

本机python列表在不应该的情况下总是比非本机链表更快(根据理论)

我在上述测试中得到的结果如下:

  • 本机链表=2.00000000001e-05

  • python列表=0.005576

  • 非本地链接列表=3.9000000001E-05

所以,我想知道为什么Python没有本地链表数据结构。 在Python的例子中,在我看来,从算法上讲,拥有 链表而不是标准列表,以加快标准库的某些方面

我的理解是,列表数据结构是该语言的一个关键构建块,它使代码更易于维护和优化,以专注于该数据结构


还有其他原因吗?

这只是因为构建列表花费了大部分时间,而不是append方法。因此,当它不是如您所示的线性时间操作时,(例如:n^2操作),append方法将比building更重要,后者将导致您想要看到的结果。

事实上,Python没有本地链表实现,我也想知道为什么

您可能想考虑的一个替代方案是(“双端队列”),它在两端提供非常快的恒定时间O(1)插入。事实上,对于您的具体示例,DEGO比链表更好,因为您不需要在中间插入。 但是,一般来说,重要的是要记住,deque是与链表不同的数据结构。链表还提供在中间插入恒定时间O(1),而DEQE仅在中间提供线性时间O(n)插入。换句话说,在DEQE的中间插入一个元素所需的时间与DeQE的当前长度N成正比,对于足够大的N,它将比链表慢。 collections.deque与真实链表之间的比较 在内部,collections.deque实际上是使用链表实现的。但是,这是一个实现细节,更重要的是,它被实现为固定大小的元素块的链接列表,而不是单个元素的链接列表

这就是为什么插入到集合的中间。DEQO是O(n)而不是O(1):仍然需要修改整个DEGK内存的大约一半,以适应新的元素N:< /P>。

before inserting N: [ABCDE]⇄[FGHIJ]⇄[KLM__]
after inserting N:  [ABCDE]⇄[FGNHI]⇄[JKLM_]
changed memory:                ^^^   ^^^^

相反,使用一个真正的链表(=单个元素),在中间插入一个新的元素N只包括分配一个新的节点和更新四个指针的值,这是一个独立于当前链表大小的操作:

before inserting N: [A]⇄[B]⇄[C]⇄[D]⇄[E]⇄[F]⇄[G]⇄    [H]⇄[I]⇄[J]⇄[K]⇄[L]⇄[M]
after inserting N:  [A]⇄[B]⇄[C]⇄[D]⇄[E]⇄[F]⇄[G]⇄[N]⇄[H]⇄[I]⇄[J]⇄[K]⇄[L]⇄[M]
changed memory:                                ^ ^ ^                           
取舍是,deque具有更好的内存局部性,并且需要更少的独立内存分配。例如,在上面的deque中插入新元素N根本不需要任何新的内存分配。这就是为什么在实践中,特别是如果你经常插入端而不是中间,一个DeQue事实上是一个比链表更好的选择。

注意,在DEQUE的中间插入元素是O(n),在开始或结束插入新元素是O(1):

警告 当然,对于链表插入实际上是O(1),这假设您已经有了一个句柄
h
,可以在该句柄之前或之后插入新节点
n
。在LinkedList的一个假设实现中,这可能如下所示:

n = linkedlist.insertbefore(h, "some value")
其中:

type(h)     # => <class 'Node'>
type(n)     # => <class 'Node'>
n.value     # => "some value"
n.next == h # => True

这意味着,只有在保留这些节点句柄的情况下,链表才值得用于某些问题。这也使API变得不那么方便,尽管每个操作都是O(1),但如果你小心的话,常数通常要大得多。所以在实践中,它们并不经常有用,这可能就是为什么它们不是Python中内置的链表的原因。

我在测试中看到两个
打印
和三个结果-你的“原生”链表来自哪里?我用不同的实现运行了多次测试,另外,我用swig构建了这个快速且超级脏的代码。你是否在问“为什么开发人员决定从python中排除链表DS?”p.s.我认为这个问题有点主观,所以可能是程序员。SE?你是对的,但是对于标准库来说,在Python中实现本机链表会有什么好处,以便潜在地加速处理大量数据的任何现有应用程序。在循环中,您附加到
b
,但在
a
之前加上前缀,这是故意的吗?
n = linkedlist.insertbefore(h, "some value")
type(h)     # => <class 'Node'>
type(n)     # => <class 'Node'>
n.value     # => "some value"
n.next == h # => True
def insert(self, i, x):
    node = self.node_from_index(i)       # Find the i-th node: O(n)
    return self.insertbefore(node, x)    # Insert and return new node: O(1)