2011-03-08 9 views

Respuesta

279

rebanar una lista

top5 = array[:5] 
  • para cortar una lista, hay una sintaxis simple: array[start:stop:step]
  • Puede omitir cualquier parámetro. Estas son todas válidas: array[start:], array[:stop], array[::step]

Cortando un generador

import itertools 
top5 = itertools.islice(my_list, 5) # grab the first five elements 
  • No se puede cortar un generador directamente en Python. itertools.islice() envolverá un objeto en un nuevo generador de división utilizando la sintaxis itertools.islice(generator, start, stop, step)

  • Recuerde, cortar un generador lo agotará parcialmente.Si desea mantener intacto todo el generador, tal vez convertirla en una tupla o lista de principio, como: result = tuple(generator)

+22

También tenga en cuenta que 'itertools.islice' devolverá un generador. –

+0

¿Por qué te estás complicando? Simplemente arroje el 'mi_lista [: 5]' y todas nuestras vidas ahora son simples – OverCoder

+10

La pregunta era "generador o lista". Estos tienen dos respuestas diferentes. 'islice' es la respuesta incorrecta para una lista, pero la respuesta correcta para un generador. Limpié la respuesta un poco para aclarar esto. – lunixbochs

82
import itertools 

top5 = itertools.islice(array, 5) 
+2

esta debería ser la respuesta aceptada. – jfs

+1

Esto también tiene la buena propiedad de devolver toda la matriz cuando tiene Ninguno en lugar de 5. –

+0

y si desea tomar los cinco que siguen cada vez puede usar: iter (matriz) en lugar de matriz. – yucer

-2

Esto debería funcionar

top5 = array[:5] 
4

¿Quiere decir que los primeros N elementos, o los N mayores artículos?

Si desea que la primera:

top5 = sequence[:5] 

Esto también funciona para los mayores elementos N, en el supuesto de que su secuencia se ordena en orden descendente. (. Su ejemplo LINQ parece asumir esto también)

Si desea que el más grande, y que no está ordenada, la solución más obvia es ordenar primero:

l = list(sequence) 
l.sort(reverse=True) 
top5 = l[:5] 

Para una más performante solución, utilizar un min-heap (gracias Thijs):

import heapq 
top5 = heapq.nlargest(5, sequence) 
+0

¿no sería el más pequeño primero? –

+0

Erm, whoops. Arreglará. – Thomas

+0

+1 para responder a pesar de la obvia ambigüedad de la pregunta – demongolem

-2

Usted tiene que usar rebanadas:

Prueba esto:

>>> lst = [1,2,3,4,5] 

>>> lst[:2] 
[1, 2] 

Toma de índice 0 al índice 2.

También puede hacer cosas como:

>>> lst = [1,2,3,4,5] 

>>> lst[2:4] 

[3, 4] 
22

En mi gusto, también es muy concisa para combinar 'zip()' con 'xrange (n) '(o' rango (n) 'en Python3), que también funciona bien en los generadores y parece ser más flexible para los cambios en general.

# Option #1: taking the first n elements as a list 
[x for _, x in zip(xrange(n), generator)] 

# Option #2, using 'next()' and taking care for 'StopIteration' 
[next(generator) for _ in xrange(n)] 

# Option #3: taking the first n elements as a new generator 
(x for _, x in zip(xrange(n), generator)) 

# Option #4: yielding them by simply preparing a function 
# (but take care for 'StopIteration') 
def top_n(n, generator): 
    for _ in xrange(n): yield next(generator) 
3

Con itertools obtendrá otro objeto generador, así que en la mayoría de los casos será necesario un paso más al dar los primeros N elementos (N). Hay al menos dos soluciones más simples (un poco menos eficiente en términos de rendimiento, pero muy práctico) para obtener los elementos listos para usar de una generator:

Utilizando lista por comprensión:

first_N_element=[generator.next() for i in range(N)] 

lo contrario:

first_N_element=list(generator)[:N] 

Donde N es el número de elementos que desea tomar (por ejemplo, N = 5 para los primeros cinco elementos).

6

La respuesta para saber cómo hacer esto se puede encontrar here

>>> generator = (i for i in xrange(10)) 
>>> list(next(generator) for _ in range(4)) 
[0, 1, 2, 3] 
>>> list(next(generator) for _ in range(4)) 
[4, 5, 6, 7] 
>>> list(next(generator) for _ in range(4)) 
[8, 9] 

en cuenta que la última llamada para la siguiente pregunta 4, cuando sólo 2 están quedando. El uso de list() en lugar de [] es lo que hace que la comprensión finalice en la excepción StopIteration lanzada por next().

8

@ La respuesta de Shaikovsky es excelente, pero quería aclarar un par de puntos.

[next(generator) for _ in range(n)]

Este es el enfoque más simple, pero los tiros StopIteration si el generador es prematuramente agotado.


Por otro lado, los siguientes enfoques volver hastan artículos, que es sin duda preferible en la mayoría de circunstancias:

lista: [x for _, x in zip(range(n), records)]

Generador: (x for _, x in zip(range(n), records))

+0

¿Podrían estas pocas personas votar esta respuesta por favor explique por qué? –

Cuestiones relacionadas