2012-02-24 13 views
6

Tengo un generador que quiero iterar en dos niveles. El primer nivel está espaciado de manera desigual, luego quiero dividir el siguiente nivel en grupos de 5, por ejemplo. Necesito que sea eficiente desde el punto de vista de la memoria y trabaje en las entradas de los generadores, así que estoy haciendo algo como lo siguiente. Tengo que pensar que puede haber una mejor manera? En particular, no quiero los Nones finales en los resultados de longitud desigual.mero con una secuencia de tamaño de fragmento en python?

import itertools 

def dynamic_grouper(iterable, intervals): 
    for i in intervals: 
     inner_iter = list(itertools.islice(iterable, i)) # this is a "group" 
     yield inner_iter 

iterable = iter(xrange(100)) 
chunk_sizes = [22,30,38,10] 

for i,group in enumerate(dynamic_grouper(iterable, chunk_sizes)): 
    args = [iter(group)] * 5 
    for item in itertools.izip_longest(fillvalue=None, *args): 
     print "Group %i" % i 
     print "Items %s" % list(item) 

Respuesta

5

Para evitar los None s, se puede usar chunks:

def chunks(seq, n): 
    # https://stackoverflow.com/a/312464/190597 (Ned Batchelder) 
    """ Yield successive n-sized chunks from seq.""" 
    for i in xrange(0, len(seq), n): 
     yield seq[i:i + n] 

for i,group in enumerate(dynamic_grouper(iterable, chunk_sizes)): 
    for item in chunks(group, 5): 
     print "Group %i" % i 
     print "Items %s" % list(item) 
+0

Gracias, esto parece que hace el truco. – jseabold

+0

¿Qué efecto tiene 'len (l)' en 'l' si es un generador? ¿No forzará eso una lectura completa de 'l', p. 'trozos (file.readlines(), 2)'? – Harvey

+0

'l' es una lista, no un generador. Aplicar 'len' a un generador generaría un TypeError. Tenga en cuenta que 'dynamic_grouper' genera listas, por lo que arriba,' group' es una lista. Entonces, llamar 'chunks (group, 5)' está bien. – unutbu

Cuestiones relacionadas