如何切片双端队列?[重复]

发布于 2021-01-29 16:02:16

这个问题已经在这里有了答案

将切片符号与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中切片为双端队列?

关注者
0
被浏览
47
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    尝试itertools.islice()

     deque_slice = collections.deque(itertools.islice(my_deque, 10, 20))
    

    索引到adeque要求每次都从头开始跟踪链接列表,因此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()方法或类似方法。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看