解析大文件时的内存错误 - Python

时间:2012-11-21 08:00:55

标签: python list memory

有人质疑Python中的内存错误,但我想问一下我的具体情况。我是编程和Python的新手。

解析大文本文件(~8GB)时,行

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

导致“MemoryError”。

我在Windows XP 64位上运行64位Python [MSC v.1500 64位(AMD64)],内存为12GB。除了安装更多RAM之外,我该如何处理这个内存错误?

4 个答案:

答案 0 :(得分:5)

内存错误即将发生,因为您正试图将整个文件存储在列表中(在内存中)。因此,尝试在每一行上工作而不是存储它:

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

答案 1 :(得分:3)

这取决于您对列表的要求。

如果你想逐行工作,你可以使用列表生成器而不是列表推导来完成工作,如下所示:

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

(不是我[...]更改了(...))。这将返回迭代器而不是列表,并且由于for line in f也不会创建列表,所以您将一次加载一行。

如果你想同时处理所有行,你可能需要将它与另一种不使用你所有记忆的技术结合起来。

答案 2 :(得分:1)

你绝对应该使用延迟生成器一次解析一行这么大的文件,或者将文件分成较小的块。

一种可能性:

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)

编辑:你也可以用一种整齐的“流水线”方式组合发电机:

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)

答案 3 :(得分:1)

我对它的看法是使用with来简化错误,生成器定义lines应该是什么样的,然后迭代它:

with open('somefile') as fin:
    lines = (line.strip('\n').split('|') for line in fin)
    for line in lines:
        pass # do something with line