Python中整数的O(1)可索引deque

Python中整数的O(1)可索引deque,python,collections,Python,Collections,我有什么选择?我需要调用大量的appends(右端)和poplefts(自然是从左端),但也需要从存储的中间读取,这将根据算法的性质稳步增长。我希望所有这些操作都在O(1)中 我可以很容易地用C语言在循环寻址数组(单词是什么?)上实现它,当数组满时,它会自动增长;但是Python呢?指向其他语言的指针也很受欢迎(我意识到“collections”标记更面向Java等,并希望进行比较,但作为次要目标) 我有Lisp的背景,在Python中从列表中删除head元素是一个O(n)操作,这让我很惊讶。一

我有什么选择?我需要调用大量的
append
s(右端)和
popleft
s(自然是从左端),但也需要从存储的中间读取,这将根据算法的性质稳步增长。我希望所有这些操作都在
O(1)

我可以很容易地用C语言在循环寻址数组(单词是什么?)上实现它,当数组满时,它会自动增长;但是Python呢?指向其他语言的指针也很受欢迎(我意识到“collections”标记更面向Java等,并希望进行比较,但作为次要目标)


我有Lisp的背景,在Python中从列表中删除head元素是一个
O(n)
操作,这让我很惊讶。一个<代码> DeQue/代码>可能是一个答案,除了文档中所说的Access是中间的代码> o(n)< /代码>。是否还有其他预构建的内容?

访问lisp列表的中间也是O(n)

Python
list
s是数组列表,这就是为什么弹出头部代价高昂(弹出尾部是固定时间)

你要找的是一个头部有(摊销)恒定时间删除的数组;这基本上意味着您必须在
列表
上构建一个数据结构,该结构使用延迟删除,并且能够在队列为空时回收延迟删除的插槽

或者,使用一个哈希表和两个整数来跟踪当前连续的键范围。

可能会对您有所帮助,尽管我不确定access是否为
O(1)
您可以使用两个python列表来获得一个分期O(1)数据结构,一个保存deque的左半部分,另一个保存deque的右半部分。前半部分是反向存储的,因此deque的左端位于列表的后面。大概是这样的:

class mydeque(object):

  def __init__(self):
    self.left = []
    self.right = []

  def pushleft(self, v):
    self.left.append(v)

  def pushright(self, v):
    self.right.append(v)

  def popleft(self):
    if not self.left:
      self.__fill_left()
    return self.left.pop()

  def popright(self):
    if not self.right:
      self.__fill_right()
    return self.right.pop()

  def __len__(self):
    return len(self.left) + len(self.right)

  def __getitem__(self, i):
    if i >= len(self.left):
      return self.right[i-len(self.left)]
    else:
      return self.left[-(i+1)]

  def __fill_right(self):
    x = len(self.left)//2
    self.right.extend(self.left[0:x])
    self.right.reverse()
    del self.left[0:x]

  def __fill_left(self):
    x = len(self.right)//2
    self.left.extend(self.right[0:x])
    self.left.reverse()
    del self.right[0:x]

我不能100%确定这段代码和python列表的摊销性能之间的交互是否真的会导致每个操作的O(1),但我的直觉是这样说的。

队列不支持访问队列的中间部分。我可以在O(n)时间内从列表的开头删除一个连续的范围吗?怎么做?@WillNess,但是……python程序员仍然使用哈希表。如果您试图在“H”下查找哈希表,那么我建议您按照教程(或阅读文档)学习python提供的功能。@WillNess如果您不知道如何删除列表的一部分,那么我绝对建议您遵循python教程。@WillNess,我会给您一个提示:字典。还有Marcin,您可能会更有用一些。@Willenss您没有费心学习使用基本类型的语法,甚至没有学习内置数据类型的存在。关于这个答案,您提出的两个问题的答案都是使用标准文档或介绍性材料来学习python。非常感谢,我会考虑一下的。
del self.right[0:x]
需要O(n)个时间吗?还有
extend
?事实上,在这个算法中,我从不调用
popright
pushleft
,所以只要左侧用尽,我就用相反的右侧替换左侧。这太棒了!谢谢!是的,但是想法是,
fill\u right
fill\u left
只在每个O(n)操作中调用,因此每个操作都需要摊销O(1)时间。我很确定,除非大小是有界的(你在Q for a C实现中提到的调整大小也会使其成为O(n)最坏的情况),否则你所问的问题只能在摊销O(1)时间内实现。是的,我理解这一点,偶尔O(n)是好的(但比O(n)更坏,这是我的意思)。对不起,我不清楚。但是由于我从来没有调用过
popright
pushleft
,唯一一个耗尽精力的是
left
,我将使用反向的
right
!我将直接在代码中互换使用这两个列表。非常感谢你!代码
q=mydeque();q、 左推(1);打印(q.popright())
崩溃,因为
\u fill\u left
函数仅将
1//2==0
元素从“左”列表传输到“右”列表。通常,这可能是相关的。