2013-07-08 35 views
0

我正在使用一個網絡庫,它會返回一個生成器,其中每個Next()調用都會接收到任意數量的文本(作爲字符串);如果你簡單地連接每個Next()調用的結果,看起來像一個標準的英文文本文件。是否有一個生成器可以將文本流轉換爲一串流?

從每個Next()調用返回的字符串中可能有多個換行符,可能沒有。返回的字符串不一定以換行符結束,即一行文本可能跨越多個Next()調用。

我想在需要Next()的第二個庫中使用這些數據來返回一行文本。在整個流程中我都沒有閱讀是絕對重要的。這可能是幾十千兆字節的數據。

是否有內置庫來解決這個問題?如果沒有,是否有人可以提出寫出發電機的最佳方法或解決問題的另一種方法?

+0

不知道接收文本的結構,這是很難回答的。請添加更多您的問題 – inspectorG4dget

+0

文本的結構是否真的很重要?這是一串帶有換行符的文本數據。發生器正在返回字符串。 – Chuu

+0

你可以使用'for stream.split('\ n')中的line來建立自己的:yield line'嗎? – wflynny

回答

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 
+0

在Python 2.4中,由於.join和next(...)的重載尚不存在,因此這需要稍作更改。 – Chuu

0

閱讀完編輯之後,也許你可以修改返回任意數量文本的流對象?例如,在stream.next()方法中,當調用.next()時,流會以某種方式生成字符串,並返回yields。你能做些什麼:

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並繼續如上。

相關問題