Cómo iterar sobre una lista en trozos
Tengo un script de Python que toma como entrada una lista de números enteros, que necesito para trabajar con cuatro números enteros a la vez. Desafortunadamente, no tengo control de la entrada, o la pasaría como una lista de tuplas de cuatro elementos. Actualmente, lo estoy repitiendo de esta manera:
for i in range(0, len(ints), 4):
# dummy op for example code
foo += ints[i] * ints[i + 1] + ints[i + 2] * ints[i + 3]
Sin embargo, se parece mucho a "C-think", lo que me hace sospechar que hay una forma más pitónica de abordar esta situación. La lista se descarta después de la iteración, por lo que no es necesario conservarla. ¿Quizás algo como esto sería mejor?
while ints:
foo += ints[0] * ints[1] + ints[2] * ints[3]
ints[0:4] = []
Aunque todavía no "se siente" bien. :-/
Actualización: con el lanzamiento de Python 3.12, cambié la respuesta aceptada. Para cualquiera que aún no haya dado (o no pueda) dar el salto a Python 3.12, le recomiendo que consulte la respuesta aceptada anterior o cualquiera de las otras excelentes respuestas compatibles con versiones anteriores que aparecen a continuación.
Pregunta relacionada: ¿Cómo se divide una lista en fragmentos de tamaño uniforme en Python?
def chunker(seq, size):
return (seq[pos:pos + size] for pos in range(0, len(seq), size))
Funciona con cualquier secuencia:
text = "I am a very, very helpful text"
for group in chunker(text, 7):
print(repr(group),)
# 'I am a ' 'very, v' 'ery hel' 'pful te' 'xt'
print('|'.join(chunker(text, 10)))
# I am a ver|y, very he|lpful text
animals = ['cat', 'dog', 'rabbit', 'duck', 'bird', 'cow', 'gnu', 'fish']
for group in chunker(animals, 3):
print(group)
# ['cat', 'dog', 'rabbit']
# ['duck', 'bird', 'cow']
# ['gnu', 'fish']
Modificado de la sección Recetas de los documentos de Python itertools
:
from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
Ejemplo
grouper('ABCDEFGHIJ', 3, 'x') # --> 'ABC' 'DEF' 'GHI' 'Jxx'
Nota: en Python 2 utilice izip_longest
en lugar de zip_longest
.
chunk_size = 4
for i in range(0, len(ints), chunk_size):
chunk = ints[i:i+chunk_size]
# process chunk of size <= chunk_size