2010-03-17 10 views
9

dado una listamanera idiomática de tomar grupos de n elementos de una lista en Python?

A = [1 2 3 4 5 6] 

¿Hay alguna forma idiomática (Pythonic) para iterar sobre ella como si se tratara de

B = [(1, 2) (3, 4) (5, 6)] 

que no sea la indexación? Que se siente como un vestigio de C:

for a1,a2 in [ (A[i], A[i+1]) for i in range(0, len(A), 2) ]: 

no puedo evitar sentir que debería haber alguna artilugio ingenioso usando itertools o rebanar o algo así.

(Por supuesto, dos a la vez es sólo un ejemplo; me gustaría una solución que funciona para cualquier n.)

Editar: relacionado Iterate over a string 2 (or n) characters at a time in Python pero incluso la solución más limpia (aceptado, usando postal) doesn Generalizar bien a mayor n sin una lista de comprensión y * -notación.

+0

Creo que su remanente C no se ve tan mal, pero me gustaría escribir 'A [i: i + 1]' en lugar de 'A [i], A [ i + 1] '. Es más fácil extenderse a 'n' arbitrario. –

+1

Duplicado: ¿Cuál es la forma más "pitónica" de iterar en una lista en fragmentos? http://stackoverflow.com/questions/434287/what-is-the-most-pythonic-way-to-iterate-over-a-list-in-chunks Vea también http://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks-in-python http://stackoverflow.com/questions/1335392/iteration-over-list-slices http://stackoverflow.com/questions/760753/iterate-over-a-python-sequence-in-multiple-of-n – jfs

+0

La [respuesta aceptada referenciada] (http://stackoverflow.com/a/1162636/923794) en realidad tiene una versión limpia, no -copiar solución, y no hay necesidad de una lista de comprensión o * -notación. Al final, querrás recorrer los datos en algún lugar, por lo que cualquier bucle/comprehensiones/generador no tendrá un precio extra. Encapsule la solución referenciada itertools.islice en una función si le gusta más compacta. – cfi

Respuesta

11

De http://docs.python.org/library/itertools.html:

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

i = grouper(3,range(100)) 
i.next() 
(0, 1, 2) 
+0

Esto puede no ser subjetivamente idiomático o evitar las listas de comprensión y * notación, pero es lo suficientemente "pitónico" para estar en la documentación. – MattH

+0

Ah, sabía que existía en alguna parte. ¡Gracias! – Wang

Cuestiones relacionadas