0

有人问过关于 Python 中的内存错误的问题,但我想问一个更具体的问题。我是编程和 Python 的新手。

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

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

导致“内存错误”。

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

4

4 回答 4

5

内存错误即将到来,因为您试图将整个文件存储在一个列表中(在内存中)。因此,尝试处理每一行而不是存储它:

for line in f:
   data = line.strip('\n').split('|')
   #do something here with data
于 2012-11-21T08:03:19.757 回答
3

这取决于你想用你的列表做什么。

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

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

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

如果您想同时处理所有行,您可能必须将其与另一种技术结合使用,以免占用所有内存。

于 2012-11-21T08:06:34.833 回答
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)
于 2012-11-21T08:07:22.523 回答
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
于 2012-11-21T08:27:14.340 回答