python читает определенные строки из файла и продолжает

Я пытаюсь прочитать определенные строки из файла и продолжить чтение после завершения процесса каждого фрагмента. Допустим, у меня в файле 19000 строк. Каждый раз я извлекаю первые 19 строк, делаю некоторые вычисления с этими строками и записываю результат в другой файл. Затем я снова извлеку следующие 19 строк и проделаю ту же обработку. Итак, я попытался извлечь строки следующим образом:

n=19
x = defaultdict(list)

i=0

fp = open("file")
for next_n_lines in izip_longest(*[fp] *n):
    lines = next_n_lines

    for i, line in enumerate(lines): 
        do calculation
    write results

Здесь код работает для первого фрагмента. Не мог бы кто-нибудь из вас помочь мне, как я могу продолжить на следующий n номер чанка? Заранее большое спасибо!


person Blue Ice    schedule 29.04.2013    source источник
comment
Ваш код уже выполняет итерацию строк группами по 19 строк. В чем проблема?   -  person Francis Avila    schedule 29.04.2013
comment
@Francis Avila: проблема, с которой я сталкиваюсь, состоит в том, чтобы перейти к следующему фрагменту. Это работает только для первого чанка.   -  person Blue Ice    schedule 29.04.2013
comment
Нет, он будет перебирать все фрагменты. Вы уверены, что нет другой проблемы с кодом, который вы не показываете? Может где-то break?   -  person Francis Avila    schedule 29.04.2013
comment
@Francis Avila: На самом деле, во втором цикле for у меня возникли проблемы. Я хочу работать с первым фрагментом во втором цикле for, после записи результатов первого фрагмента я хочу снова перейти к следующему фрагменту.   -  person Blue Ice    schedule 29.04.2013


Ответы (3)


Ваш код уже извлекает строки группами по 19 строк, поэтому я не уверен, в чем ваша проблема.

Я могу немного подчистить ваше решение, но оно делает то же самое, что и ваш код:

from itertools import izip_longest

# grouping recipe from itertools documentation
def grouper(n, iterable, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

def process_chunk(chunk):
    "Return sequence of result lines.  Chunk must be iterable."
    for i, line in enumerate(chunk):
        yield 'file-line {1:03d}; chunk-line {0:02d}\n'.format(i, int(line))
    yield '----------------------------\n'

Вот некоторый тестовый код, который демонстрирует, что посещается каждая строка:

from StringIO import StringIO

class CtxStringIO(StringIO):
    def __enter__(self):
        return self
    def __exit__(self, *args):
        return False

infile = CtxStringIO(''.join('{}\n'.format(i) for i in xrange(19*10)))
outfile = CtxStringIO()


# this should be the main loop of your program.
# just replace infile and outfile with real file objects
with infile as ifp, outfile as ofp:
    for chunk in grouper(19, ifp, '\n'):
        ofp.writelines(process_chunk(chunk))

# see what was written to the file
print ofp.getvalue()

Этот тестовый пример должен печатать такие строки:

file-line 000; chunk-line 00
file-line 001; chunk-line 01
file-line 002; chunk-line 02
file-line 003; chunk-line 03
file-line 004; chunk-line 04
...
file-line 016; chunk-line 16
file-line 017; chunk-line 17
file-line 018; chunk-line 18
----------------------------
file-line 019; chunk-line 00
file-line 020; chunk-line 01
file-line 021; chunk-line 02
...
file-line 186; chunk-line 15
file-line 187; chunk-line 16
file-line 188; chunk-line 17
file-line 189; chunk-line 18
----------------------------
person Francis Avila    schedule 29.04.2013
comment
Большое спасибо за такое хорошее решение! - person Blue Ice; 29.04.2013

Это решение не требует загрузки всех строк в память.

n=19
fp = open("file")
next_n_lines = []
for line in fp:
    next_n_lines.append(line)
    if len(next_n_lines) == n:
        do caculation
        next_n_lines = []
if len(next_n_lines) > 0:
    do caculation
write results
person ArkChar    schedule 29.04.2013
comment
Спасибо за ваше предложение и решение! - person Blue Ice; 29.04.2013
comment
@BlueIce также может иметь дело со случаями, когда количество строк в файле не кратно 19. - person ArkChar; 29.04.2013

Это неясно в вашем вопросе, но я думаю, что ваши вычисления зависят от всех N строк, которые вы извлекаете (19 в вашем примере).

Поэтому лучше извлечь все эти строки, а затем выполнить работу:

N = 19
inFile = open('myFile')
i = 0
lines = list()

for line in inFile:
    lines.append(line)
    i += 1
    if i == N:
        # Do calculations and save on output file
        lines = list()
        i = 0
person halflings    schedule 29.04.2013
comment
Спасибо @halflings! Да, мой расчет зависит от всех 19 строк. попробую с твоей. Спасибо еще раз! - person Blue Ice; 29.04.2013
comment
Я только что заметил, что в моем решении, вероятно, есть ошибка (возможно, я неправильно проверяю конец файла), изменю его через секунду. - person halflings; 29.04.2013