如何切片双端队列?[重复]
这个问题已经在这里有了答案 :
将切片符号与collections.deque一起使用 (6个答案)
6年前关闭。
我已将一些使用列表的代码更改为使用双端队列。我不能再切入它,因为出现错误:
TypeError:序列索引必须是整数,而不是’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))
索引到a
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()
放置一个。我将其保留为练习。:-)deque
通过if
切片测试,从中检索单个项目的性能将稍有下降。如果这是一个问题,则可以使用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()
方法或类似方法。