我會先讀取所有在內存據稱,大文件作爲行的列表:
with open('socalledbig.txt', 'rt') as f:
lines = f.readlines()
應該多一點4MB - 微小甚至今天的手機標準,電腦更普通。
然後,執行您需要的任何處理來確定您想要寫入較小文件的每組行的開始和結尾(我不確定您的問題的文本中這些組是否可以重疊或留下空白,所以我提供了他們完全被允許的最通用的解決方案 - 這也將覆蓋更多受限的用例,並沒有真正的性能損失,但如果約束非常嚴格,代碼可能會更簡單。
說你把這些數字在列表starts
(指數從0第一行寫的,包括在內),ends
(指數從第一行的0不寫 - 可以合法和innocuosly是len(lines)
以上),names
(你想寫的文件名),所有列表當然具有相同的長度。
然後,最後:
assert len(starts) == len(ends) == len(names)
for s, e, n in zip(starts, ends, names):
with open(n, 'wt') as f:
f.writelines(lines[s:e])
......而這一切,你需要做的!
編輯:所述OP似乎是由具有這些列表的概念混淆,所以讓我嘗試舉一個例子:寫出到文件中的每個塊開始於含有'begin'
(包含)的線和結束於包含'end'
(也包含在內)的第一個緊接後面的行,並且要寫入的文件的名稱應爲result0.txt
,result1.txt
等等。 如果「關閉結束」的數量與「開始打開」的數量不同(並且記住,第一個緊接着的「結束」結束所有未決的「開始」)是錯誤的。不允許包含'begin'和'end'的行。
非常任意設定的條件,可以肯定的,但隨後的OP使我們完全在有關該問題的實際細節黑暗,所以我們還能做,但我想大多數瘋狂 - ?)
outfile = 0
starts = []
ends = []
names = []
for i, line in enumerate(lines):
if 'begin' in line:
if 'end' in line:
raise ValueError('Both begin and end: %r' % line)
starts.append(i)
names.append('result%d.txt' % outfile)
outfile += 1
elif 'end' in line:
ends.append(i + 1) # remember ends are EXCLUDED, hence the +1
就是這樣 - 關於具有相同長度的三個列表的assert
將負責檢查約束是否受到尊重。
由於約束和規範的更改,因此當然會因此該代碼段的變化 - 只要它填補了三個等長名單starts
,ends
和names
,究竟如何它這樣做的事項對代碼的其餘部分來說並不重要。
那裏不會在組中重疊寫,但可能不得不在兩者之間留有一條線之間的空白.. 請告訴我們上述代碼中的開始,結尾和名稱是什麼更明確.. – kaki 2010-06-22 16:24:12
@kaki,好吧,我認爲我很清楚,但我會添加一個完全虛假的例子(因爲我們根本不知道細節)試圖進一步幫助你 - 讓我編輯它。 – 2010-06-22 16:38:20
thnq u回覆 – kaki 2010-06-22 17:26:52