Я хочу переглянути кожен рядок цілого файлу. Один із способів зробити це - прочитати весь файл, зберегти його у вигляді списку, а потім пройтись по рядку, що цікавить. Цей метод використовує багато пам'яті, тому я шукаю альтернативу.
Мій код на даний момент:
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)
Виконання цього коду видає повідомлення про помилку: пристрій активний
.
Є пропозиції?
Мета - обчислити попарну схожість рядків, тобто для кожного рядка у файлі я хочу обчислити відстань Левенштейна з кожним іншим рядком.
Два способи ефективного використання пам'яті у ранжованому порядку (перший найкращий) -
with
- підтримується починаючи з python 2.5 і вищеyield
, якщо ви дійсно хочете мати контроль над тим, скільки читатиwith
## 1.with
- це гарний та ефективний пітонівський спосіб читання великих файлів. переваги - 1) файловий об'єкт автоматично закривається після виходу з блоку виконання with
. 2) обробка виключних ситуацій всередині блоку with
. 3) цикл роботи з пам'яттю for
перебирає файловий об'єкт f
рядок за рядком. Внутрішньо він виконує буферизований ввід/вивід (для оптимізації на дорогих операціях вводу/виводу) та управління пам'яттю.
with open("x.txt") as f:
for line in f:
do something with data
yield
Іноді вам може знадобитися більш тонкий контроль над тим, скільки зчитувати у кожній ітерації. У такому випадку використовуйте iter & yield. Зауважте, що при використанні цього методу потрібно явно закривати файл в кінці.
def readInChunks(fileObj, chunkSize=2048):
"""
Lazy function to read a file piece by piece.
Default chunk size: 2kB.
"""
while True:
data = fileObj.read(chunkSize)
if not data:
break
yield data
f = open('bigFile')
for chuck in readInChunks(f):
do_something(chunk)
f.close()
Підводні камені та для повноти картини - наведені нижче методи не є такими ж гарними або елегантними для читання великих файлів, але, будь ласка, прочитайте, щоб отримати загальне уявлення про них.
У Python найпоширенішим способом читання рядків з файлу є наступний:
for line in open('myfile','r').readlines():
do_something(line)
Однак, коли це робиться, функція readlines()
(те ж саме стосується і функції read()
) завантажує весь файл у пам'ять, а потім виконує над ним ітерацію. Дещо кращим підходом (перші два згадані методи є найкращими) для великих файлів є використання модуля fileinput
, як показано нижче:
import fileinput
for line in fileinput.input(['myfile']):
do_something(line)
виклик fileinput.input()
зчитує рядки послідовно, але не зберігає їх у пам'яті після зчитування або навіть просто так, оскільки file
у python є ітерабельним.
це можливий спосіб читання файлу в python:
f = open(input_file)
for line in f:
do_stuff(line)
f.close()
не виділяє повний список. Він виконує ітерацію по рядках.
З документації на python для fileinput.input():
Перебирає рядки всіх файлів, перерахованих в
ys.argv[1:]
, за замовчуванням переходить доys.stdin
, якщо список порожній
далі йде опис функції:
fileinput.FileInput([files[, inplace[, backup[, mode[, openhook]]]]])
Читаючи між рядків, це говорить мені, що files
може бути списком, так що ви можете мати щось на кшталт:
for each_line in fileinput.input([input_file, input_file]):
do_something(each_line)
Дивіться тут для отримання додаткової інформації