Какой лучший способ разделить строку на фиксированные длины и работать с ними в Python?

Я читаю строку из текстового файла, используя:

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

и выводит его на ЖК-дисплей шириной 16 символов в команде telnetlib.write. Если чтение строки длиннее 16 символов, я хочу разбить ее на разделы длиной 16 символов и вытолкнуть каждую секцию после определенной задержки (например, 10 секунд), после того, как код будет перемещен на следующую строку входного файла и продолжить.

Я пробовал искать различные решения и читать на itertools и т.д., но мое понимание Python просто недостаточно для того, чтобы заставить что-либо работать, не делая этого очень долго, используя запутанный беспорядок, если бы тогда были утверждения else что, вероятно, собирается связать меня в узлах!

Какой лучший способ для меня сделать то, что я хочу?

Ответы

Ответ 1

Одним из решений было бы использовать эту функцию:

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

Эта функция возвращает генератор, используя понимание генератора. Генератор возвращает строку, нарезанную, от 0 + кратное длине кусков, до длины кусков + кратное длине кусков.

Вы можете перебирать генератор как список, кортеж или строку - for i in chunkstring(s,n): , или преобразовать его в список (например) с помощью list(generator). Генераторы более эффективны с точки зрения памяти, чем списки, потому что они генерируют свои элементы по мере необходимости, а не сразу, однако им не хватает определенных функций, таких как индексирование.

Этот генератор также содержит меньший фрагмент в конце:

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

Пример использования:

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)

Ответ 2

Моим любимым способом решить эту проблему является модуль re.

import re

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

Одно из предостережений заключается в том, что re.findall не возвращает кусок, который меньше значения длины, поэтому любой остаток пропускается.

Однако, если вы анализируете данные фиксированной ширины, это отличный способ сделать это.

Например, если я хочу проанализировать блок текста, который, как я знаю, состоит из 32 байтовых символов (например, заголовок), я нахожу это очень читаемым и не вижу необходимости обобщать его на отдельную функцию (как в chunkstring):

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

Ответ 3

Я знаю это старое, но хотел бы добавить, как разрезать строку с столбцами переменной длины:

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))