2011-08-15 10 views

Respuesta

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

Por ejemplo:

>>> 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] 

Esto debería ser más eficientes las otras soluciones publicadas hasta ahora. ¿Prueba?

[[email protected]]$ SETUP="import itertools,collections; q=collections.deque(xrange(1000000))" 

[[email protected]]$ python -m timeit "$SETUP" "list(itertools.islice(q, 10000, 20000))" 
10 loops, best of 3: 68 msec per loop 

[[email protected]]$ python -m timeit "$SETUP" "[q[i] for i in xrange(10000, 20000)]" 
10 loops, best of 3: 98.4 msec per loop 

[[email protected]]$ python -m timeit "$SETUP" "list(q)[10000:20000]" 
10 loops, best of 3: 107 msec per loop 
+0

Muy agradable. Como tiene un ejemplo completo, quizás 'q.extend (rango (10, 20))' podría ser mejor. –

+0

@rm sí, 'q.extend (..)' estaría bien. De hecho, se debe usar 'q = deque (xrange (10,20))'. Simplemente copié el ejemplo de OP tal como está. Respuesta actualizada –

2
output = [q[i] for i in range(3,6+1)] 
1

yo preferiría esto, es más corta por lo más fácil de leer:

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

Pero hace dos copias de 'deque' (una completa, una parcial) en lugar de una copia parcial. No es un problema si el 'deque' es corto, pero podría ser si es largo. – agf

+0

Es cierto, eso. Pero entonces, este no es realmente un caso de uso para un 'deque'. La otra solución crea una lista para el 'rango'. Pensaría en esto como el 'list (set (list))' hack para encontrar elementos únicos de una lista: elegante y bonita, pero quizás no la más eficiente. –

+0

Sin embargo, podría sustituir el rango por 'xrange' y no crearía una lista; también, considere si desea una porción corta de un' deque' largo; la lista parcial y/o el rango serían pequeños, pero la copia completa sería un problema. – agf

1

me gustaría añadir esto como una nueva respuesta, para proporcionar un mejor formato.

Para simplificar, la respuesta de Shawn es perfecta, pero si a menudo necesita obtener un segmento del dequeue, puede preferir crear una subclase y agregar un método __getslice__.

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

esto no va a apoyar el establecimiento de un nuevo segmento, pero se puede implementar su propio encargo __setslice__ método que utiliza el mismo concepto.