64

項目 3..6dequeを変更せずに、次の項目から効率的かつエレガントに Python で抽出するにはどうすればよいでしょうか。

from collections import deque
q = deque('',maxlen=10)
for i in range(10,20):
    q.append(i)

スライス表記がうまくいかないようですdeque...

4

6 に答える 6

88
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
于 2011-08-15T12:15:56.890 に答える
7

私はこれを好むでしょう、それはより短いので読みやすいです:

output = list(q)[3:6+1]
于 2011-08-15T12:02:35.220 に答える
3
output = [q[i] for i in range(3,6+1)]
于 2011-08-15T11:15:08.993 に答える
3

メソッドをオーバーライドし て、 using__getitem__を作成できます。SliceableDequeislice

考慮すべき特殊なケースがあります (たとえば、負のスライスの使用は では機能しません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))
于 2019-01-21T14:17:30.480 に答える