Use slice notation with collections.deque Use slice notation with collections.deque python python

Use slice notation with collections.deque


import itertoolsoutput = list(itertools.islice(q, 3, 7))

For example:

>>> import collections, itertools>>> q = collections.deque(xrange(10, 20))>>> qdeque([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])>>> list(itertools.islice(q, 3, 7))[13, 14, 15, 16]

This should be more efficient the the other solutions posted so far. Proof?

[me@home]$ SETUP="import itertools,collections; q=collections.deque(xrange(1000000))"[me@home]$ python -m timeit  "$SETUP" "list(itertools.islice(q, 10000, 20000))"10 loops, best of 3: 68 msec per loop[me@home]$ python -m timeit "$SETUP" "[q[i] for i in  xrange(10000, 20000)]"10 loops, best of 3: 98.4 msec per loop[me@home]$ python -m timeit "$SETUP" "list(q)[10000:20000]"10 loops, best of 3: 107 msec per loop


I would prefer this, it's shorter so easier to read:

output = list(q)[3:6+1]


I'd add this as a new answer, to provide better formatting.

For simplicity, Shawn's answer is perfect, but if you often need to get a slice from dequeue, you might prefer to subclass it and add a __getslice__ method.

from collections import dequefrom itertools import isliceclass deque_slice(deque):    def __new__(cls, *args):        return deque.__new__(cls, *args)    def __getslice__(self, start, end):        return list(islice(self, start, end))

This won't support setting a new slice, but you can implement your own custom __setslice__ method using the same concept.

NOTE: this is valid for Python <=2.* only. It's also worth noticing that, while __getslice__ is deprecated since python 2.0, the documentation still reports this for the latest 2.7 release:

(However, built-in types in CPython currently still implement __getslice__(). Therefore, you have to override it in derived classes when implementing slicing.)