2012-03-12 17 views
103

Tengo una lista de Python que se ejecuta en 1000's. Algo así como:Dividir una lista de python en otras "sublistas", es decir, listas más pequeñas

data=["I","am","a","python","programmer".....] 

donde, len (datos) = dicen 1003

Ahora me gustaría crear un subconjunto de esta lista (de datos) mediante el fraccionamiento de la lista original en trozos de 100. Por lo tanto, en al final, Id gustaría tener algo como:

data_chunk1=[.....] #first 100 items of list data 
data_chunk2=[.....] #second 100 items of list data 
. 
. 
. 
data_chunk11=[.....] # remainder of the entries,& its len <=100, len(data_chunk_11)=3 

¿hay una manera Pythonic para lograr esta tarea? Obviamente puedo usar datos [0: 100] y demás, pero estoy asumiendo que es terriblemente no-pitónico y muy ineficiente.

Muchas gracias.

+3

puede usar [array_split función de numpy ] (https://docs.scipy.org/doc/numpy/reference/generated/numpy.array_split.html#numpy.array_split) por ejemplo, 'np.array_split (np.array (data), 20)' para dividir en 20 pedazos de tamaño casi igual. Para asegurarse de que los trozos sean exactamente iguales, use 'np.split'. – AlexG

Respuesta

200

diría

chunks = [data[x:x+100] for x in xrange(0, len(data), 100)] 

Si está utilizando Python 3.x range() reemplaza Python 2.x de xrange(), cambiando el código anterior para:

chunks = [data[x:x+100] for x in range(0, len(data), 100)] 
+3

Iría con eso también. ¡Podrías hacerlo de una manera más "pitónica" con itertools, pero será feo como el pecado! –

+6

Si tienes una lista y quieres una lista, no hay razón para molestarse con itertools. tiene sentido si desea dividir una secuencia de datos sin crear nunca todo. – alexis

+3

Usar itertools sería en realidad la forma menos pitónica de hacerlo, ¿no? – Pastafarian

6
chunks = [data[100*i:100*(i+1)] for i in range(len(data)/100 + 1)] 

Esto es equivalente a la respuesta aceptada. Por ejemplo, acortando a lotes de 10 para facilitar la lectura:

data = range(35) 
print [data[x:x+10] for x in xrange(0, len(data), 10)] 
print [data[10*i:10*(i+1)] for i in range(len(data)/10 + 1)] 

Salidas:

[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34]] 
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34]] 
+2

Eso no es lo que se pide. –

+0

En realidad es equivalente, a excepción de un error donde falta el último lote, ahora corregido. – qris

24

En realidad creo que el uso de las rebanadas llano es la mejor solución en este caso:

for i in range(0, len(data), 100): 
    chunk = data[i:i + 100] 
    ... 

Si quiere evitar copiar las rebanadas, puede usar itertools.islice(), pero no parece ser necesario aquí.

La documentación itertools() también contiene la famosa "mero" patrón:

def grouper(n, iterable, fillvalue=None): 
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" 
    args = [iter(iterable)] * n 
    return izip_longest(fillvalue=fillvalue, *args) 

Usted tendría que modificarlo para tratar el último trozo correctamente, así que creo que la solución recta hacia adelante usando rebanadas de fricción es preferible.

+0

gracias por la respuesta. Pensé en tu primera solución de corte simple, pero pensé que era demasiado ineficiente y demasiado ingenua de mi parte ... Estoy un poco sorprendido de que no haya una manera pitónica (una línea) para lograr esta tarea :( – JohnJ

Cuestiones relacionadas