2012-04-12 54 views
-1

我正在尋找一種很好的方式來編寫一個生成器,該生成器需要從另一個列表/生成器/迭代中的項目流並對它們進行分組。分組生成器的Pythonic模式

分割項目很容易。舉例來說,如果我們要採取一個文件的行及將它們分爲字符:

def lines2chars(filename): 

    with open(filename) as fh: 

     for line in fh:     # Iterate over items 
      for char in line:   # Split items up 
       yield char    # Yield smaller items 

將它們分組,產生的段落,例如,似乎很棘手。這是我想出的:

def lines2para(filename): 

    with fh as open(filename): 
     paragraph = []     # Start with an empty group 

     while True:      # Infinite loop to be ended by exception 
      try: 
       line = next(fh)   # Get a line 
      except StopIteration as e: 
             # If there isn't one... 
             # do whatever necessary 
       raise     # and raise StopIteration for the caller 
      else: 
       paragraph.append(line) # Add to the group of items 
       if line == "\n":  # If we've got a whole group 
        yield paragraph  # yield it 
        paragraph = []  # and start a new group 

這在我看來並不漂亮。它使用迭代協議的內部,有一個無限循環被打破,而且對我來說讀起來並不好。那麼有沒有人有更好的方式來編寫這種類型的代碼?

請記住,我正在尋找的模式,而不是這個具體的例子。在我的情況下,我正在讀取跨數據包分割的數據,但每個級別都與段落示例類似。

+2

http://docs.python.org/library/itertools.html#itertools.groupby有什麼問題? – luke14free 2012-04-12 09:02:14

+0

這個問題的答案是否有幫助? http://stackoverflow.com/q/3862010/311220 – Acorn 2012-04-12 09:06:31

+0

@ luke14free嗯,絕對適用於該段落的例子,但你讓我意識到,對於我的分組數據流,我需要保持一個運行的數量有多少數據是在每個數據包中。我的例子不夠好。我會稍微更新一下我的問題,但我需要繼續工作,否則我會比我早。 – 2012-04-12 09:13:05

回答

1
import itertools as it 

def lines2para(filename): 
    with open(filename) as fh: 
     for k, v in it.groupby(fh, key=lambda x: bool(x.strip())): 
      if k: 
       yield list(v) 
+0

你已經回答了我的問題,但我意識到我的問題不是我所需要的。我會稍微重新編輯 – 2012-04-12 09:14:34