Какой лучший способ разделить строку на фиксированные длины и работать с ними в 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))