Ваш опубликованный код считывает весь файл и создает копию файла в памяти в виде единого списка всего содержимого файла, разбитого на кортежи, по одному кортежу на строку. Поскольку вы спрашиваете, как использовать меньше памяти, вам может понадобиться только функция генератора:
def readfile(filepath, delim):
with open(filepath, 'r') as f:
for line in f:
yield tuple(line.split(delim))
НО! Существует серьезная оговорка! Вы можете перебирать кортежи, возвращенные readfile, только один раз.
lines_as_tuples = readfile(mydata,','):
for linedata in lines_as_tuples:
# do something
Пока все в порядке, генератор и список выглядят одинаково. Но предположим, что ваш файл будет содержать много чисел с плавающей запятой, и ваша итерация по файлу вычислит общее среднее из этих чисел. Вы можете использовать код «# do what» для вычисления общей суммы и количества чисел, а затем вычислить среднее значение. Но теперь предположим, что вы хотели повторить итерацию, на этот раз, чтобы найти отличия от среднего для каждого значения. Вы бы подумали, что просто добавите еще один цикл:
for linedata in lines_as_tuples:
# do another thing
# BUT - this loop never does anything because lines_as_tuples has been consumed!
БАМ! Это большая разница между генераторами и списками. На данный момент в коде генератор полностью использован - но особых исключений не возникает, цикл for просто ничего не делает и продолжает молча!
Во многих случаях список, который вы получите, будет повторяться только один раз, и в этом случае преобразование файла чтения в генератор будет правильным. Но если вам нужен более постоянный список, к которому вы будете обращаться несколько раз, то простое использование генератора создаст вам проблемы, поскольку вы можете перебирать генератор только один раз.
Мое предложение? Сделайте readlines генератором, чтобы в своем собственном небольшом представлении о мире он просто выдавал каждый инкрементный бит файла, красиво и эффективно занимая память. Возьмите на себя ответственность за сохранение данных на вызывающем объекте - если вызывающий объект должен ссылаться на возвращенные данные несколько раз, то вызывающий элемент может просто создать свой собственный список из генератора - это легко сделать в Python, используя list(readfile('file.dat', ','))
.