Use slice notation with collections.deque
This is an old question, but for any future travelers, the Python docs explicitly recommend using rotate
for this:
The rotate() method provides a way to implement deque slicing and deletion.
https://docs.python.org/2/library/collections.html
An implementation is relatively simple:
def slice_deque(d, start, stop, step):
d.rotate(-start)
slice = list(itertools.islice(d, 0, stop-start, step))
d.rotate(start)
return slice
Effectively the same as using islice
directly, except that rotate
is more efficient for skipping through to the starting point. On the other hand, it also temporarily modifies the deque, which could be a threadsafety concern.
I would prefer this, it's shorter so easier to read:
output = list(q)[3:6+1]
import itertools
output = list(itertools.islice(q, 3, 7))
For example:
>>> import collections, itertools
>>> q = collections.deque(xrange(10, 20))
>>> q
deque([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