Есть ли альтернативы приведенному ниже коду:
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)
со строками неизвестной, но разной длины, и мне нужно перейти к определенной строке, какой номер я знаю заранее? Я чувствую себя плохо, обрабатывая их один за другим, когда знаю, что могу проигнорировать хотя бы первую половину файла. Ищу более элегантное решение, если оно есть.
python
text-files
user63503
источник
источник
Ответы:
linecache :
источник
Вы не можете продвигаться вперед, не прочитав файл хотя бы один раз, так как вы не знаете, где находятся разрывы строк. Вы можете сделать что-то вроде:
источник
У вас действительно не так много вариантов, если строки имеют разную длину ... вам, к сожалению, нужно обработать символы окончания строки, чтобы знать, когда вы перешли к следующей строке.
Однако вы можете значительно ускорить это И уменьшить использование памяти, изменив последний параметр на «open» на значение, отличное от 0.
0 означает, что операция чтения файла не буферизуется, что очень медленно и занимает много места на диске. 1 означает, что файл буферизирован по строкам, что было бы улучшением. Все, что выше 1 (скажем, 8k ... то есть: 8096 или выше), читает фрагменты файла в память. Вы по-прежнему
for line in open(etc):
получаете к нему доступ , но python работает только понемногу, отбрасывая каждый буферизованный фрагмент после его обработки.источник
Я наверное избалован обильным тараном, но 15 М - это не так уж и много. Чтение в память с помощью
readlines()
- это то, что я обычно делаю с файлами такого размера. Доступ к строке после этого тривиален.источник
Я удивлен, что никто не упомянул islice
или если вы хотите, чтобы весь остальной файл
или если вы хотите, чтобы каждая вторая строка из файла
источник
Поскольку невозможно определить длину всех строк, не прочитав их, у вас нет другого выбора, кроме как перебрать все строки перед вашей начальной строкой. Все, что вы можете сделать, это сделать так, чтобы он выглядел красиво. Если файл действительно огромен, вы можете использовать подход на основе генератора:
Примечание: при таком подходе индекс равен нулю.
источник
Если вы не хотите читать весь файл в памяти ... вам может потребоваться какой-нибудь формат, отличный от обычного текста.
конечно, все зависит от того, что вы пытаетесь сделать, и как часто вы будете перепрыгивать через файл.
Например, если вы собираетесь много раз переходить к строкам в одном и том же файле и знаете, что файл не изменяется во время работы с ним, вы можете сделать это:
сначала пройти через весь файл и записать " seek-location "некоторых номеров ключевых строк (например, когда-либо 1000 строк).
Затем, если вы хотите строку 12005, перейдите на позицию 12000 (которую вы записали), затем прочтите 5 строк, и вы узнаете себя в очереди 12005 и так далее
источник
Если вы заранее знаете позицию в файле (а не номер строки), вы можете использовать file.seek () для перехода к этой позиции.
Изменить : вы можете использовать функцию linecache.getline (имя файла, белье) , которая вернет содержимое строки белье, но только после чтения всего файла в память. Хорошо, если вы произвольно обращаетесь к строкам из файла (как сам python может захотеть распечатать трассировку), но не подходит для файла размером 15 МБ.
источник
Что создает файл, который вы хотите обработать? Если это что-то под вашим контролем, вы можете сгенерировать индекс (какая строка в какой позиции) во время добавления файла. Индексный файл может иметь фиксированный размер строки (заполненные пробелами или 0 числа) и определенно будет меньше. И поэтому их можно быстро читать и обрабатывать.
источник
У меня была такая же проблема (нужно получить из огромной строки файла).
Конечно, я могу каждый раз пробегать все записи в файле и останавливать его, когда счетчик будет равен целевой строке, но это не работает эффективно в случае, когда вы хотите получить множественное количество определенных строк. Это привело к решению главной проблемы - как обращаться непосредственно к нужному месту файла.
Я узнал следующее решение: сначала я заполнил словарь с начальной позицией каждой строки (ключ - номер строки, а значение - суммарная длина предыдущих строк).
в конечном итоге прицельная функция:
t.seek (номер_строки) - команда, выполняющая обрезку файла до начала строки. Итак, если вы в следующий раз зафиксируете строку чтения - вы получите целевую строку.
Используя такой подход, я сэкономил значительную часть времени.
источник
Вы можете использовать mmap, чтобы найти смещение линий. MMap кажется самым быстрым способом обработки файла
пример:
затем используйте f.seek (смещения), чтобы перейти к нужной строке
источник
Содержат ли сами строки какую-либо информацию индекса? Если бы содержание каждой строки было чем-то вроде "
<line index>:Data
", тоseek()
подход можно было бы использовать для выполнения двоичного поиска по файлу, даже если количествоData
переменных. Вы должны искать середину файла, читать строку, проверять, выше или ниже ее индекс, чем тот, который вам нужен, и т. Д.В противном случае лучшее, что вы можете сделать, - это просто
readlines()
. Если вы не хотите читать все 15 МБ, вы можете использоватьsizehint
аргумент, чтобы, по крайней мере, заменить многоreadline()
s меньшим количеством вызововreadlines()
.источник
Если вы имеете дело с текстовым файлом, основанным на системе Linux , вы можете использовать команды linux.
Для меня это сработало!
источник
Вот пример использования readlines (sizehint) для чтения фрагмента строк за раз. DNS указал на это решение. Я написал этот пример, потому что другие примеры здесь ориентированы на одну строку.
источник
Ни один из ответов не является особенно удовлетворительным, поэтому вот небольшой фрагмент, который поможет.
Пример использования:
Это включает в себя множество поисков файлов, но это полезно в тех случаях, когда вы не можете уместить весь файл в памяти. Он выполняет одно начальное чтение, чтобы получить расположение строк (так что он читает весь файл, но не сохраняет его в памяти), а затем каждый доступ выполняет поиск файла постфактум.
Я предлагаю приведенный выше фрагмент под лицензией MIT или Apache на усмотрение пользователя.
источник
Можно использовать эту функцию для возврата строки n:
источник