我正在使用一个网络库,该网络库返回一个生成器,每次Next()调用都会收到任意数量的文本(作为字符串);如果你只是简单地连接每个Next()调用的结果;看起来像标准的英文文本。
每个Next()调用返回的字符串中可能有多个换行符,可能没有。返回的字符串不一定以换行符结尾,即一行文本可以分布在多个Next()调用中。
我试图在第二个库中使用这个数据,需要Next()返回一行文本。绝对关键我不读整个流;这可能是数十亿字节的数据。
是否有内置库来解决此问题?如果没有,有人可以建议编写生成器的最佳方法或另一种解决问题的方法吗?
答案 0 :(得分:2)
编写一个生成器函数,将块拉下来并将它们分成几行。由于您不知道最后一行是否以换行符结尾,请保存并将其附加到下一个块。
def split_by_lines(text_generator):
last_line = ""
try:
while True:
chunk = "".join(last_line, next(text_generator))
chunk_by_line = chunk.split('\n')
last_line = chunk_by_line.pop()
for line in chunk_by_line:
yield line
except StopIteration: # the other end of the pipe is empty
yield last_line
raise StopIteration
答案 1 :(得分:0)
阅读完编辑后,您可以修改返回任意数量文本的流对象吗?例如,在stream.next()
方法中,当调用yields
时,流会以某种方式生成字符串并.next()
。你能做点什么:
def next(self):
if '\n' in self.remaining:
terms = self.remaining.split('\n')
to_yield, self.remaining = terms[0], ''.join(terms[1:])
yield to_yield
else:
to_yield = self.remaining + self.generate_arbitrary_string()
while '\n' not in to_yield:
to_yield += self.generate_arbitrary_string()
to_yield, self.remaining = terms[0], ''.join(terms[1:])
yield to_yield
此伪代码假定流对象使用generate_arbitrary_string()
生成一些任意字符串。在您第一次调用next()
时,self.remaining
字符串应为空,因此您转到else
语句。在那里,你连接任意字符串,直到找到newline
字符,在第一个newline
字符处拆分连接字符串,产生前半部分并将后半部分存储在remaining
中。
在next()
的后续通话中,您首先检查self.remaining
是否包含任何newline
个字符。如果是这样,产生第一行并存储其余部分。如果没有,请将新的任意字符串附加到self.remaining
并继续如上所述。