如何使用Python的csv模块高效导出字典为csv文件?内存溢出错误
我正在尝试使用Python的CSV模块将一个字典列表序列化成一个CSV文本文件。我的列表大约有13,000个元素,每个元素都是一个字典,里面有大约100个键,内容包括简单的文本和数字。我的函数“dictlist2file”只是调用了DictWriter来进行序列化,但我遇到了内存不足的错误。
我的函数是:
def dictlist2file(dictrows, filename, fieldnames, delimiter='\t',
lineterminator='\n', extrasaction='ignore'):
out_f = open(filename, 'w')
# Write out header
if fieldnames != None:
header = delimiter.join(fieldnames) + lineterminator
else:
header = dictrows[0].keys()
header.sort()
out_f.write(header)
print "dictlist2file: serializing %d entries to %s" \
%(len(dictrows), filename)
t1 = time.time()
# Write out dictionary
data = csv.DictWriter(out_f, fieldnames,
delimiter=delimiter,
lineterminator=lineterminator,
extrasaction=extrasaction)
data.writerows(dictrows)
out_f.close()
t2 = time.time()
print "dictlist2file: took %.2f seconds" %(t2 - t1)
当我在我的字典上尝试这个时,得到的输出是:
dictlist2file: serializing 13537 entries to myoutput_file.txt
Python(6310) malloc: *** mmap(size=45862912) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Traceback (most recent call last):
...
File "/Library/Frameworks/Python.framework/Versions/6.2/lib/python2.6/csv.py", line 149, in writerows
rows.append(self._dict_to_list(rowdict))
File "/Library/Frameworks/Python.framework/Versions/6.2/lib/python2.6/csv.py", line 141, in _dict_to_list
return [rowdict.get(key, self.restval) for key in self.fieldnames]
MemoryError
有没有人知道这可能是什么原因呢?这个列表只有13,000个元素,而这些字典本身也很简单和小(100个键),所以我不明白为什么会导致内存错误或者效率这么低。它花了几分钟才出现内存错误。
谢谢你的帮助。
4 个回答
1
你可能遇到了Python内部的问题。建议你去bugs.python.org上报告一下。
3
DictWriter.writerows(...)
这个方法会把你传给它的所有字典都拿来,创建一个新的列表,每一行对应一个列表。所以如果你的数据量很大,就可能会出现 MemoryError
的错误。你可以考虑以下两种方法:
- 自己遍历这个列表,然后对每一个字典调用一次
DictWriter.writerow
。不过这样会导致很多次写入。 - 把行分成小的列表,然后对这些小列表调用
DictWriter.writerows
。这样写入次数会少一些,但可以避免一次性占用太多内存。
0
我不知道csv到底发生了什么,但我发现下面这个替代方法可以在几秒钟内把字典保存到文件里:
for row in dictrows:
out_f.write("%s%s" %(delimiter.join([row[name] for name in fieldnames]),
lineterminator))
这里的dictrows是通过csv中的DictReader生成的字典生成器,fieldnames是一个字段名称的列表。
如果有人知道为什么csv的表现不一样,那就太好了,谢谢!