你可以使用一個GROUPBY假設該部分通過啓動#TYPE
線劃定:
from itertools import groupby, chain
def get_sections(fle):
with open(fle) as f:
grps = groupby(f, key=lambda x: x.lstrip().startswith("#TYPE"))
for k, v in grps:
if k:
yield chain([next(v)], (next(grps)[1])) # all lines up to next #TYPE
你可以得到每節爲你迭代:
In [13]: cat in.txt
#TYPE Lorem.Text.A
first
#TYPE Lorem.Text.B
second
#TYPE Lorem.Text.C
third
In [14]: for sec in get_sections("in.txt"):
....: print(list(sec))
....:
['#TYPE Lorem.Text.A\n', 'first\n']
['#TYPE Lorem.Text.B\n', 'second\n']
['#TYPE Lorem.Text.C\n', 'third\n']
如果沒有其他行以#
然後單獨將足以在startswith使用,有沒有在你的模式複雜,所以它不是一個真正的正則表達式的用例。這也只是將一段文件一次不存儲到整個文件中。
如果你沒有前導空白,唯一的地方#
出現是TYPE之前可能就足夠了就叫GROUPBY:
from itertools import groupby, chain
def get_sections(fle):
with open(fle) as f:
grps = groupby(f)
for k, v in grps:
if k:
yield chain([next(v)], (next(grps)[1])) # all lines up to next #TYPE
如果有一些元數據在一開始,你可以使用dropwhile跳過線直到我們打#Type
,然後就組:
from itertools import groupby, chain, dropwhile
def get_sections(fle):
with open(fle) as f:
grps = groupby(dropwhile(lambda x: not x.startswith("#"), f))
for k, v in grps:
if k:
yield chain([next(v)], (next(grps)[1])) # all lines up to next #TYPE
演示:
In [16]: cat in.txt
meta
more meta
#TYPE Lorem.Text.A
first
#TYPE Lorem.Text.B
second
second
#TYPE Lorem.Text.C
third
In [17]: for sec in get_sections("in.txt"):
print(list(sec))
....:
['#TYPE Lorem.Text.A\n', 'first\n']
['#TYPE Lorem.Text.B\n', 'second\n', 'second\n']
['#TYPE Lorem.Text.C\n', 'third\n']
我會檢查你的建議。 –
@AdrianZ ..它肯定會工作,並避免在存儲器中存儲多個數據副本,如果你使用。閱讀與re.split你將存儲在內存中的數據的兩個完整副本,如果您的文件很大可能不可能 –
它看起來非常好,我喜歡不浪費內存的想法。現在我沒有從打印輸出中獲得輸出,但我會繼續測試一下,然後返回結果。 –