2017-06-07 83 views
0

我有一個含有像這樣記錄的文件單個發電機:消費由多個過濾發電機

>uniqueid#BARCODE1 
content content 
content content 
>uniqueid#BARCODE2 
content content 
content content 
>uniqueid#BARCODE1 
content content 
content content 
... 

還有約10萬條記錄與〜300個獨特的條形碼和條形碼的順序是隨機的。我的目標是將文件分成300個文件。我想通過一個產生記錄的生成器只傳遞一次文件。

我已經通過多次讀取文件或將整個文件加載到內存中解決了這個問題。我想用一種生成器方法解決這個問題,以減少內存使用量,並且只讀取一次文件。

是否可以實例化300個生成器並具有一些將記錄分派給正確生成器的邏輯?然後我可以簡單地寫出每個生成器的內容到一個文件中。我是否需要對所有300個文件都打開,以便一次寫入?

+0

什麼是你想要的輸出?應如何調用文件? –

+0

它是來自真實文件還是一些僞數據的示例? –

+0

是的,有可能 - 甚至可能有更好的方法來做你想做的事。請編輯您的問題,並添加一些示例代碼和更真實的示例輸入文件數據。 – martineau

回答

1

是的,它可以用發電機完成,但我們不需要其中的300個,只有1個就足夠了。

據我瞭解'uniqueid#BARCODE1'條形碼由兩個部分組成:

  • '>uniqueid#'前綴,
  • 'BARCODE1'條形碼本身。

所以讓我們開始寫一個簡單的檢查

BAR_CODE_PREFIX = '>uniqueid#' 


def is_bar_code(text): 
    return text.startswith(BAR_CODE_PREFIX) 

然後解析條形碼的內容,我們可以寫發電機

def parse_content(lines): 
    lines_iterator = iter(lines) 
    # we assume that the first line is a barcode 
    bar_code = next(lines_iterator) 
    contents = [] 
    for line in lines_iterator: 
     if is_bar_code(line): 
      # next barcode is found 
      yield bar_code, contents 
      bar_code = line 
      contents = [] 
     else: 
      contents.append(line) 
    # to yield last barcode with its contents 
    yield bar_code, contents 

那麼假設你希望把條形碼的文件後,我們可以寫

def split_src(src_path): 
    with open(src_path) as src_file: 
     for bar_code, content_lines in parse_content(src_file): 
      bar_code_index = bar_code[len(BAR_CODE_PREFIX):].rstrip('\n') 
      # we use `append` mode 
      # because in the different parts of file 
      # there are contents of the same barcode 
      with open(bar_code_index, mode='a') as dst_file: 
       dst_file.writelines(content_lines) 

正好走o通過整個文件的新時間。

測試

讓我們創建src.txt文件,其中包括

>uniqueid#BARCODE1 
content11 
>uniqueid#BARCODE2 
content21 
>uniqueid#BARCODE1 
content12 
content12 
>uniqueid#BARCODE3 
content31 
>uniqueid#BARCODE2 
content22 

然後調用

split_src('src.txt') 

會有創建下一個文件後:

  • BARCODE1用線

    content11 
    content12 
    content12 
    
  • BARCODE2用線

    content21 
    content22 
    
  • BARCODE3用線

    content31 
    
+0

我不清楚這個問題,但我想避免打開和關閉文件1000萬次。這個答案確實符合我提出的方式的問題標準。 – elsherbini

+0

@elsherbini:你可以用更多的細節更新問題 –