Сначала я бы прочитал весь предположительно большой файл в памяти как список строк:
with open('socalledbig.txt', 'rt') as f:
lines = f.readlines()
должен занимать чуть больше 4 МБ - крошечный даже по стандарту современных телефонов , гораздо меньше обычных компьютеров .
Затем выполните любую необходимую обработку, чтобы определить начало и конец каждой группы строк, которые вы хотите записать в меньшие файлы (яЯ не уверен по тексту вашего вопроса, могут ли такие группы перекрываться или оставлять пропуски, поэтому я предлагаю наиболее общее решение, когда им это полностью разрешено - это также охватит более ограниченные варианты использования без реального снижения производительности,хотя код мог бы быть немного проще, если бы ограничения были очень жесткими).
Скажем, что вы помещаете эти числа в списки starts
(индекс от 0 первой строки для записи, включенный), ends
(индексот 0 первой строки до НЕ писать - может быть законно и безобидно быть 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])
... и это все, что вам нужно сделать!
Редактировать : ОПкажется, что смущает концепция наличия этих списков, поэтому позвольте мне привести пример: каждый блок, записываемый в файл, начинается со строки, содержащей '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
, в точности как это так важно, что ни в коей мере не относится к остальной части кода.