0

我正在使用一个网络库,该库返回一个生成器,您在每次 Next() 调用时都会收到任意数量的文本(作为字符串);如果您只是连接每个 Next() 调用的结果;看起来像一个标准的英文文本文件。

每个 Next() 调用返回的字符串中可能有多个换行符,也可能没有。返回的字符串不一定以换行符结尾,即一行文本可以分布在多个 Next() 调用中。

我正在尝试在需要 Next() 返回一行文本的第二个库中使用此数据。我没有阅读整个流,这绝对是至关重要的;这可能是数十 GB 的数据。

是否有内置库来解决这个问题?如果没有,有人可以建议编写生成器的最佳方法或解决问题的替代方法吗?

4

2 回答 2

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
于 2013-07-08T22:34:33.113 回答
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并像上面一样继续。

于 2013-07-08T22:33:26.200 回答