为什么在collections.deque中添加或删除比在那里查找更慢?

时间:2015-09-11 18:35:53

标签: python time-complexity deque

这个关于某些数据结构算法复杂性的wiki.python.org页面说明了collections.deque对象的以下内容:

  

deque(双端队列)在内部表示为双向链表。 (好吧,一个数组列表而不是对象,以提高效率。)两端都可以访问,但即使看中间也很慢,中间增加或删除速度较慢。

两个问题:

1)是否可以添加到deque的中间?我在API中没有看到任何方法。

2)为什么在deque的中间删除(或添加)比查找慢?它是一个双向链表,所以一旦找到想要添加的对象,添加/删除应该是一个恒定的时间操作。

3 个答案:

答案 0 :(得分:3)

  1. 可以使用remove()方法或del关键字删除项目。无法插入项目。 (唯一可能的方法是插入不会出现在API文档中的切片分配,并且deque上的内容无效。)
  2. 因为,正如描述所说,它实际上是一个双向链接的数组列表。因此,插入或移除内容可能需要将元素从一个数组移动到另一个数组。 (我还没看过实现,但我知道deque在查找元素时使用了一个步幅技术,我假设所用数组的大小与步长相同,即62。)在删除项目时,您必须在常规list内移动大量内存,但至少它们都在一个块中,并且可以有效地移动。

答案 1 :(得分:3)

可以使用python3.5插入。 index(), insert(), and copy()是仅在python3.5new in python 3.5中可用的三种新方法,在早期版本中无法插入双端队列:

  

deque类现在定义了index(),insert()和copy(),并支持+*运算符。这允许将deques识别为MutableSequence并提高它们对列表的可替代性。 (供稿人:Raymond Hettinger issue 23704。)

您可以使用deldeque.remove从双端队列中移除:

 deq = deque([1,2,3,4,5,6])
 del deq[4] 
 deq.remove(3) 

答案 2 :(得分:1)

1)看起来在Python 3.5中添加了deque.insert()

2)从来源:https://github.com/python/cpython/blob/d16a1520c2b22c3cbde7547937ba283db3e88ff5/Modules/_collectionsmodule.c#L952-L958

  

insert(),remove()和delitem()是按照实现的     rotate()为了简单和接近结束的合理性能     点。如果出于某种原因这些方法变得流行,则不然     难以使用直接数据移动重新实现这一点(类似于     列表切片分配中使用的代码)并实现性能     提升(通过仅移动每个指针一次而不是两次)。

它变慢的原因是它的实施方式。