Я хочу выполнить итерацию по каждой строке всего файла. Один из способов сделать это - прочитать весь файл, сохранить его в списке, затем перейти к интересующей строке. Этот метод использует много памяти, поэтому я ищу альтернативу.
Мой код пока:
for each_line in fileinput.input(input_file): do_something(each_line)
for each_line_again in fileinput.input(input_file): do_something(each_line_again)
Выполнение этого кода выдает сообщение об ошибке: device active.
Есть предложения?
Цель состоит в том, чтобы вычислить попарное сходство строк, что означает, что для каждой строки в файле я хочу вычислить расстояние Левенштейна с каждой другой строкой.
Ноябрь 2022 Правка: Связанный вопрос, который был задан через 8 месяцев после этого вопроса, содержит много полезных ответов и комментариев. Чтобы получить более глубокое понимание логики Python, также прочитайте этот связанный с этим вопрос Как я должен читать файл построчно в Python?
Переведено автоматически
Ответ 1
Правильный, полностью Pythonic способ чтения файла следующий:
withopen(...) as f: for line in f: # Do something with 'line'
Оператор with обрабатывает открытие и закрытие файла, в том числе, если во внутреннем блоке возникает исключение. for line in f Обрабатывает файловый объект f как итерируемый, который автоматически использует буферизованный ввод-вывод и управление памятью, поэтому вам не нужно беспокоиться о больших файлах.
Должен быть один - и предпочтительно только один - очевидный способ сделать это.
Ответ 2
Два способа экономии памяти в ранжированном порядке (лучше всего первый) -
использование with - поддерживается в python 2.5 и выше
используйте yield, если вы действительно хотите контролировать объем чтения
1. использование with
with это хороший и эффективный pythonic способ чтения больших файлов. преимущества - 1) файловый объект автоматически закрывается после выхода из with блока выполнения. 2) обработка исключений внутри with блока. 3) память for цикл перебирает f файловый объект построчно. внутренне он выполняет буферизованный ввод-вывод (для оптимизации дорогостоящих операций ввода-вывода) и управление памятью.
withopen("x.txt") as f: for line in f: do something with data
2. использование yield
Иногда может потребоваться более детальный контроль над объемом чтения на каждой итерации. В этом случае используйте iter & yield. Обратите внимание, что при использовании этого метода явно требуется закрыть файл в конце.
defreadInChunks(fileObj, chunkSize=2048): """ Lazy function to read a file piece by piece. Default chunk size: 2kB.
""" whileTrue: data = fileObj.read(chunkSize) ifnot data: break yield data
f = open('bigFile') for chunk in readInChunks(f): do_something(chunk) f.close()
Pitfalls and for the sake of completeness - below methods are not as good or not as elegant for reading large files but please read to get rounded understanding.
In Python, the most common way to read lines from a file is to do the following:
for line inopen('myfile','r').readlines(): do_something(line)
When this is done, however, the readlines() function (same applies for read() function) loads the entire file into memory, then iterates over it. A slightly better approach (the first mentioned two methods above are the best) for large files is to use the fileinput module, as follows:
import fileinput
for line in fileinput.input(['myfile']): do_something(line)
the fileinput.input() call reads lines sequentially, but doesn't keep them in memory after they've been read or even simply so this, since file in python is iterable.
The newline parameter is only supported in Python 3 and defaults to None, which indicates universal newline mode (input file can have any newline, output string gets \n). The mode parameter defaults to 'r' in all cases. The U is deprecated in Python 3. In Python 2 on Windows some other mechanism appears to translate \r\n to \n.