有人问过关于 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 之外,我该如何处理此内存错误?
内存错误即将到来,因为您试图将整个文件存储在一个列表中(在内存中)。因此,尝试处理每一行而不是存储它:
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)
编辑:您还可以以简洁的“流水线”方式组合生成器:
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)
我对它的看法是使用它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