2013-06-27 4 views
1

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

Например, читая последнюю строку файла, можно сделать

input_file = open('mytext.txt', 'r') 
lastLine = "" 
    for line in input_file: 
    lastLine = line 

print lastLine # This is the last line 

Или

fileHandle = open('mytext.txt', 'r') 
lineList = fileHandle.readlines() 
print lineList[-1] #This is the last line 

Я предполагаю, что для этого конкретного случая это может быть не очень уместным обсуждать эффективность .. .

Вопрос:

1. метод Wich быстрее для выбора случайной строки

2. Можем ли мы иметь дело с понятиями, как «SEEK» в Python (если так это быстрее?)

+7

Да, Python поддерживает '.seek()' вызовы объектов файлов. Почему бы вам не сделать некоторые тесты самостоятельно? 'timeit' - это модуль для правильной проверки небольших фрагментов кода и сравнения таймингов. –

+3

Метод два очень быстрый для файлов, которые намного больше, чем доступная память. Он сработает задолго до того, как будет прочитан весь файл. –

+0

И для * случайных * строк из файла вы использовали бы совсем другую технику. См. [Случайные строки Python из подпапок] (http://stackoverflow.com/q/12128948) для обсуждения того, как выбирать случайные строки из файлов. –

ответ

1

Если вам не нужно равномерное распределение (т.е. это нормально, что шанс для некоторой линии ковыряться не одинаков для всех линий) и/или если ваши линии все о тех же длинах, то проблема выбора случайной строки может быть упрощена:

  1. Определения размер файла в байтах
  2. обратиться к случайной позиции
  3. поиск последнего символа новой строки, если какой-либо (не может быть ни одного, если нет предшествующей линии)
  4. Выберите весь текст до следующего символа новой строки или конец файла, в зависимости от того, что наступит раньше.

Для (2) вы просчитали, насколько далеко вы должны искать назад, чтобы найти предыдущую новую строку. Если вы можете сказать, что строка равна n байт, вы можете прочитать предыдущие n байт за один шаг.

0

У меня была эта проблема несколько дней назад, и я использую это решение. Мое решение похоже на @Frerich Раабе один, но без случайных, просто логика :)

def get_last_line(f): 
    """ f is a file object in read mode, I just extract the algorithm from a bigger function """ 
    tries = 0 
    offs = -512 

    while tries < 5: 
     # Put the cursor at n*512nth character before the end. 
     # If we reach the max fsize, it puts the cursor at the beginning (fsize * -1 means move the cursor of -fsize from the end) 
     f.seek(max(fsize * -1, offs), 2) 
     lines = f.readlines() 
     if len(lines) > 1: # If there's more than 1 lines found, then we have the last complete line 
      return lines[-1] # Returns the last complete line 
     offs *= 2 
     tries += 1 

    raise ValueError("No end line found, after 5 tries (Your file may has only 1 line or the last line is longer than %s characters)" % offs) 

В tries счетчики избежать быть блок, если файл имеет также одну строку (очень долго последняя линия). Алгоритм пытается получить последнюю строку из последних 512 символов, затем 1024, 2048 ... и остановится, если по-прежнему нет полной строки на итерации th.

+1

Переменная 'end' никогда не инициализируется (и не задается). Кроме того, правописание PEP8 предпочтительнее в Python - 'get_last_line', а не' getLastLine'. – user4815162342

+0

Да, ты прав, отредактирован. –

+0

Вы можете удалить переменную 'end' вообще, она никогда не устанавливается нигде. 'while пытается <5: ...' BTW, если попытка достигает 5, вы можете вернуться к 'f.seek (0); return f.readlines() [- 1] 'или создать исключение. Безмолвный возврат «Нет» не делает услугу звонящего. – user4815162342