Что самый эффективный путь состоит в том, чтобы получить первую и последнюю строку текстового файла?

У меня есть текстовый файл, который содержит метку времени на каждой строке. Моя цель состоит в том, чтобы найти диапазон времени. Все времена в порядке, таким образом, первая строка будет самым ранним временем, и последняя строка будет последним временем. Мне только нужна самая первая и самая последняя строка. Каков был бы самый эффективный способ получить эти строки в Python?

Примечание: Эти файлы являются относительно большими в длине, приблизительно 1-2 миллиона строк каждый, и я должен сделать это для нескольких сотен файлов.

69
задан mik01aj 3 February 2016 в 07:03
поделиться

4 ответа

docs for io module

with open(fname, 'rb') as fh:
    first = next(fh).decode()

    fh.seek(-1024, 2)
    last = fh.readlines()[-1].decode()

Значение переменной здесь 1024: она представляет собой среднюю длину строки. Я выбираю 1024 только для примера. Если у вас есть оценка средней длины строки, вы можете просто использовать это значение, умноженное на 2.

Поскольку вы понятия не имеете о возможной верхней границе длины строки, очевидным решением будет перебор файла:

for line in fh:
    pass
last = line

Вам не нужно возиться с двоичным флагом, вы можете просто использовать open(fname).

ETA: Поскольку у вас много файлов для работы, вы можете создать выборку из нескольких десятков файлов с помощью random.sample и запустить на них этот код для определения длины последней строки. С априорно большим значением позиционного сдвига (скажем, 1 МБ). Это поможет вам оценить значение для полного прогона.

58
ответ дан 24 November 2019 в 13:40
поделиться

Можете ли вы использовать команды unix? Я думаю, что использование head -1 и tail -n 1, вероятно, наиболее эффективные методы. В качестве альтернативы можно использовать простой fid.readline() для получения первой строки и fid.readlines()[-1], но это может занять слишком много памяти.

9
ответ дан 24 November 2019 в 13:40
поделиться

Получить первую строку тривиально просто. Для последней строки, предполагая, что вы знаете приблизительную верхнюю границу длины строки, os.lseek некоторая сумма из SEEK_END найти предпоследнюю строку, заканчивающуюся, а затем readline ( ) последняя строка.

1
ответ дан 24 November 2019 в 13:40
поделиться

Вот модифицированная версия ответа SilentGhost, которая сделает то, что вы хотите.

with open(fname, 'rb') as fh:
    first = next(fh)
    offs = -100
    while True:
        fh.seek(offs, 2)
        lines = fh.readlines()
        if len(lines)>1:
            last = lines[-1]
            break
        offs *= 2
    print first
    print last

Здесь не нужна верхняя граница для длины строки.

24
ответ дан 24 November 2019 в 13:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: