Как перейти к определенной строке в огромном текстовом файле? - PullRequest
98 голосов
/ 06 марта 2009

Есть ли альтернативы коду ниже:

startFromLine = 141978 # or whatever line I need to jump to

urlsfile = open(filename, "rb", 0)

linesCounter = 1

for line in urlsfile:
    if linesCounter > startFromLine:
        DoSomethingWithThisLine(line)

    linesCounter += 1

Если я обрабатываю огромный текстовый файл (~15MB) со строками неизвестной, но разной длины, и мне нужно перейти к определенной строке, какое число я знаю заранее? Я чувствую себя плохо, обрабатывая их один за другим, когда знаю, что могу игнорировать хотя бы первую половину файла. Ищете более элегантное решение, если оно есть.

Ответы [ 15 ]

2 голосов
/ 07 марта 2009

Содержат ли сами строки какую-либо информацию индекса? Если содержимое каждой строки было чем-то вроде «<line index>:Data», то подход seek() можно использовать для двоичного поиска в файле, даже если значение Data является переменным. Вы будете искать середину файла, читать строку, проверять, будет ли его индекс выше или ниже того, который вам нужен, и т. Д.

В противном случае лучшее, что вы можете сделать, это просто readlines(). Если вы не хотите читать все 15 МБ, вы можете использовать аргумент sizehint, чтобы хотя бы заменить множество readline() с меньшим числом вызовов на readlines().

1 голос
/ 23 марта 2016

Если вы имеете дело с текстовым файлом & на основе linux system , вы можете использовать команды linux.
Для меня это сработало хорошо!

import commands

def read_line(path, line=1):
    return commands.getoutput('head -%s %s | tail -1' % (line, path))

line_to_jump = 141978
read_line("path_to_large_text_file", line_to_jump)
1 голос
/ 07 августа 2015

Вы можете использовать mmap, чтобы найти смещение линий. MMap, кажется, самый быстрый способ обработки файла

пример:

with open('input_file', "r+b") as f:
    mapped = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
    i = 1
    for line in iter(mapped.readline, ""):
        if i == Line_I_want_to_jump:
            offsets = mapped.tell()
        i+=1

затем используйте f.seek (смещения), чтобы перейти к нужной вам строке

1 голос
/ 07 марта 2009

Вот пример использования readlines (sizehint) для чтения порций строк одновременно. DNS указал на это решение. Я написал этот пример, потому что другие примеры здесь ориентированы на одну строку.

def getlineno(filename, lineno):
    if lineno < 1:
        raise TypeError("First line is line 1")
    f = open(filename)
    lines_read = 0
    while 1:
        lines = f.readlines(100000)
        if not lines:
            return None
        if lines_read + len(lines) >= lineno:
            return lines[lineno-lines_read-1]
        lines_read += len(lines)

print getlineno("nci_09425001_09450000.smi", 12000)
0 голосов
/ 20 сентября 2015

Может использовать эту функцию для возврата строки n:

def skipton(infile, n):
    with open(infile,'r') as fi:
        for i in range(n-1):
            fi.next()
        return fi.next()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...