问过关于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 %sn" % 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