¿Cuál es la mejor manera de dividir una cadena en trozos de longitud fija y trabajar con ellos en Python?

Estoy leyendo en una línea de un archivo de texto usando:

file = urllib2.urlopen("http://192.168.100.17/test.txt").read().splitlines() 

y enviarlo a una pantalla LCD, que tiene un ancho de 16 caracteres, en un comando telnetlib.write. En el caso de que la lectura de la línea tenga más de 16 caracteres, quiero dividirla en secciones de cadenas de 16 caracteres y eliminar cada sección después de un cierto retraso (por ejemplo, 10 segundos), una vez completado, el código debe moverse a la siguiente línea del archivo de entrada y continuar.

He intentado buscar varias soluciones y leer sobre los instrumentos, etc., pero mi comprensión de Python no es suficiente para hacer que algo funcione sin hacerlo de una manera muy prolongada, utilizando un lío enmarañado de si luego hay otras declaraciones que probablemente van a funcionar. para atarme en nudos!

¿Cuál es la mejor manera de hacer lo que quiero?

Una solución sería usar esta función:

 def chunkstring(string, length): return (string[0+i:length+i] for i in range(0, len(string), length)) 

Esta función devuelve un generador, utilizando un generador de comprensión. El generador devuelve la cadena cortada, desde 0 + un múltiplo de la longitud de los trozos, hasta la longitud de los trozos + un múltiplo de la longitud de los trozos.

Puede iterar sobre el generador como una lista, tupla o cadena, for i in chunkstring(s,n): o convertirlo en una lista (por ejemplo) con list(generator) . Los generadores son más eficientes en memoria que las listas porque generan sus elementos a medida que son necesarios, no todos a la vez, sin embargo, carecen de ciertas características como la indexación.

Este generador también contiene cualquier fragmento más pequeño al final:

 >>> list(chunkstring("abcdefghijklmnopqrstuvwxyz", 5)) ['abcde', 'fghij', 'klmno', 'pqrst', 'uvwxy', 'z'] 

Ejemplo de uso:

 text = """This is the first line. This is the second line. The line below is true. The line above is false. A short line. A very very very very very very very very very long line. A self-referential line. The last line. """ lines = (i.strip() for i in text.splitlines()) for line in lines: for chunk in chunkstring(line, 16): print(chunk) 

Mi forma favorita de resolver este problema es con el módulo re .

 import re def chunkstring(string, length): return re.findall('.{%d}' % length, string) 

Una advertencia aquí es que re.findall no devolverá un fragmento que sea menor que el valor de la longitud, por lo que se omite cualquier rest.

Sin embargo, si está analizando datos de ancho fijo, esta es una excelente manera de hacerlo.

Por ejemplo, si quiero analizar un bloque de texto que sé que está formado por 32 caracteres de bytes (como una sección de encabezado), me parece muy legible y no veo la necesidad de generalizarlo en una función separada (como en chunkstring ):

 for header in re.findall('.{32}', header_data): ProcessHeader(header) 

Sé que es un oldie, pero me gusta agregar cómo cortar una cadena con columnas de longitud variable:

 def chunkstring(string, lengths): return (string[pos:pos+length].strip() for idx,length in enumerate(lengths) for pos in [sum(map(int, lengths[:idx]))]) column_lengths = [10,19,13,11,7,7,15] fields = list(chunkstring(line, column_lengths))