我正在使用以下方式从文本文件中读取一行:
file = urllib2.urlopen("http://192.168.100.17/test.txt").read().splitlines()
并在 telnetlib.write 命令中将其输出到 LCD 显示屏(16 个字符宽)。 如果读取的行长度超过 16 个字符,我想将其分解为 16 个字符长字符串的部分,并在一定延迟(例如 10 秒)后将每个部分推出,一旦完成,代码应移至下一行输入文件并继续。
我尝试过搜索各种解决方案并阅读 itertools 等,但我对 Python 的理解不足以让任何事情正常工作,除非使用一堆混乱的 if then else 语句以非常冗长的方式进行操作,这可能是会让我陷入困境!
对我来说,做我想做的事情的最佳方式是什么?
一种解决方案是使用此功能:
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)
标准库提供了 textwrap.wrap:
from textwrap import wrap
s = "some random text that should be splitted into chunks"
print(wrap(s, width=3))
['som', 'e r', 'and', 'om ', 'tex', 't t', 'hat', 'sho', 'uld', 'be ', 'spl',
'itt', 'ed ', 'int', 'o c', 'hun', 'ks']
我最喜欢的解决此问题的方法是使用
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)
用列表理解来做:
n = "aaabbbcccddd"
k = 3
[n[i:i+k] for i in range(0,len(n),k)]
=> ['aaa', 'bbb', 'ccc', 'ddd']
我知道这是一个老歌,但想添加如何用可变长度列切碎字符串:
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))
我认为这种方式更容易阅读:
string = "when an unknown printer took a galley of type and scrambled it to make a type specimen book."
length = 20
list_of_strings = []
for i in range(0, len(string), length):
list_of_strings.append(string[i:length+i])
print(list_of_strings)
变得更加简单:
str_to_split="KIMJEONG" # Your string to split here
n=4 # Your chunk length here
buf=""
ourchunks=[]
x=0
for i in str_to_split:
x += 1
buf += i
if (x % 4) == 0:
ourchunks.append(buf)
buf=""
您可以使用
itertools
现在(自 2023 年 10 月起(
import itertools
s = "QVQLVQ TVL QVQLVQSGC"
'\n'.join(
[''.join(t) for t in itertools.batched(s, 4)]
)
对于 3.12 之前的 Python 版本,您只需复制粘贴 [正版
batched
实现][1]: 的缩短版本
def batched(iterable, chunk_size):
items = iter(iterable)
while batch := tuple(itertools.islice(items, chunk_size)):
yield batch