項目 3..6deque
を変更せずに、次の項目から効率的かつエレガントに Python で抽出するにはどうすればよいでしょうか。
from collections import deque
q = deque('',maxlen=10)
for i in range(10,20):
q.append(i)
スライス表記がうまくいかないようですdeque
...
import itertools
output = list(itertools.islice(q, 3, 7))
例えば:
>>> 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]
これは、これまでに投稿された他のソリューションよりも効率的であるはずです。証拠?
[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
私はこれを好むでしょう、それはより短いので読みやすいです:
output = list(q)[3:6+1]
output = [q[i] for i in range(3,6+1)]
メソッドをオーバーライドし て、 using__getitem__
を作成できます。SliceableDeque
islice
考慮すべき特殊なケースがあります (たとえば、負のスライスの使用は では機能しませんislice
)。
ここに私が使用しているものがあります:
import itertools
from collections import deque
class SliceableDeque(deque):
def __getitem__(self, s):
try:
start, stop, step = s.start or 0, s.stop or sys.maxsize, s.step or 1
except AttributeError: # not a slice but an int
return super().__getitem__(s)
try: # normal slicing
return list(itertools.islice(self, start, stop, step))
except ValueError: # incase of a negative slice object
length = len(self)
start, stop = length + start if start < 0 else start, length + stop if stop < 0 else stop
return list(itertools.islice(self, start, stop, step))