Ошибка памяти при анализе большого файла – Python

В Python возникли вопросы о ошибках памяти, но я хочу задать еще одну конкретную ситуацию. Я новичок в программировании и Python.

При разборе большого текстового файла (~ 8 ГБ) линия

mylist = [line.strip('\n').split('|') for line in f] 

привело к «MemoryError».

Я запускаю 64-разрядный Python [MSC v.1500 64 бит (AMD64)] в Windows XP 64-бит с 12 ГБ ОЗУ. Как я могу справиться с этой ошибкой памяти, кроме установки большего количества ОЗУ?

4 Solutions collect form web for “Ошибка памяти при анализе большого файла – Python”

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

 for line in f: data = line.strip('\n').split('|') #do something here with data 

Это зависит от того, что вы хотите сделать со своим списком.

Если вы хотите работать по очереди, вы можете, вероятно, выполнить задание с помощью генератора списков вместо понимания списка, которое будет выглядеть следующим образом:

 myiterator = (line.strip('\n').split('|') for line in f) 

(не то, что я изменил [...] на (...) ). Это вернет итератор вместо списка, и поскольку for line in f также не создается список, вы будете загружать одну строку за раз.

Если вы хотите работать со всеми линиями одновременно, вам, вероятно, придется объединить это с другим методом, чтобы не использовать всю вашу память.

Вы должны обязательно использовать ленивый генератор для синтаксического анализа такого огромного файла по одной строке за раз или разделить файл на более мелкие куски.

Одна возможность:

 def lazy_reader(path): """reads a file one line at a time.""" try: file = open(path, 'r') while True: line = file.readline() if not line: break yield line # "outputs" the line from the generator except IOError: sys.stderr.write("error while opening file at %s\n" % path) sys.exit(2) finally: file.close() 

и тогда вы можете использовать свой генератор таким образом

 for line in lazy_reader("path/to/your/file"): do_something_with(line) 

EDIT: вы также можете комбинировать генераторы аккуратным «конвейерным» способом:

 def parse(generator): for line in generator: yield line.strip('\n').split('|') for data in parse( lazy_reader("path/to/your/file") ): do_something_with_splitted_array(data) 

Я беру на себя это, используя для облегчения ошибок генератор, чтобы определить, какие lines должны выглядеть, а затем повторяет это:

 with open('somefile') as fin: lines = (line.strip('\n').split('|') for line in fin) for line in lines: pass # do something with line 
Python - лучший язык программирования в мире.