我已将一些使用列表的代码更改为使用双端队列。我不能再切入它,因为我得到了错误:
TypeError: sequence index must be integer, not 'slice'
这是一个显示问题的 REPL。
>>> import collections
>>> d = collections.deque()
>>> for i in range(3):
... d.append(i)
...
>>> d
deque([0, 1, 2])
>>> d[2:]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sequence index must be integer, not 'slice'
那么,有没有一种解决方法可以支持在 Python 中分割成双端队列?
最佳答案
试试 itertools.islice()
。
deque_slice = collections.deque(itertools.islice(my_deque, 10, 20))
索引到 deque
每次都需要从头开始跟随一个链表,所以 islice()
方法,跳过项目到达切片的开头,将提供最佳性能(比将其编码为每个元素的索引操作更好)。
您可以轻松编写一个 deque
子类,自动为您执行此操作。
class sliceable_deque(collections.deque):
def __getitem__(self, index):
if isinstance(index, slice):
return type(self)(itertools.islice(self, index.start,
index.stop, index.step))
return collections.deque.__getitem__(self, index)
请注意,您不能在 islice
中使用负索引或步长值。可以围绕这个编写代码,如果您采用子类方法,这样做可能是值得的。对于负开始或停止,您只需添加双端队列的长度;对于负面步骤,您需要在某处扔一个 reversed()
。我会把它留作练习。 :-)
切片的 if
测试会略微降低从 deque
检索单个项目的性能。如果这是一个问题,您可以使用 EAFP 模式来稍微改善这一点——代价是由于需要处理异常而使切片路径的性能稍微降低:
class sliceable_deque(collections.deque):
def __getitem__(self, index):
try:
return collections.deque.__getitem__(self, index)
except TypeError:
return type(self)(itertools.islice(self, index.start,
index.stop, index.step))
当然还有一个额外的函数调用,与常规的deque
相比,所以如果你真的关心性能,你真的想添加一个单独的slice()
方法之类的。
关于python - 如何切片双端队列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10003143/