我正在尝试使用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个键),所以我不明白为什么这会导致内存错误或效率低下。它需要几分钟才能得到内存错误。
感谢您的帮助。
答案 0 :(得分:3)
DictWriter.writerows(...)
获取您传递给它的所有dicts并创建(在内存中)一个新的列表列表,每行一个。因此,如果您有大量数据,我可以看到如何弹出MemoryError
。您可以采取两种方式:
DictWriter.writerow
一次。虽然这意味着很多写作。DictWriter.writerows
。减少IO,但是你可以避免分配大量的内存。答案 1 :(得分:1)
你可能会绊倒内部Python问题。我会在bugs.python.org上报告。
答案 2 :(得分:0)
我对csv的情况没有答案,但我发现以下替代品在不到几秒的时间内将字典序列化为一个文件:
for row in dictrows:
out_f.write("%s%s" %(delimiter.join([row[name] for name in fieldnames]),
lineterminator))
其中dictrows是由dictReader从csv生成的字典生成器,fieldnames是一个字段列表。
任何有关为什么csv表现不同的想法都将非常感激。感谢。
答案 3 :(得分:0)
你说如果你遍历data.writerow(single_dict)它仍然会遇到问题。输入代码以显示每100行的行数。在获得内存错误之前处理了多少个dicts?运行更多或更少的进程以吸收更多或更少的内存...失败的地方会变化吗?
什么是max(len(d) for d in dictrows)
?字符串中的字符串有多长?
你有多少可用内存?
更新:查看Dictwriter是否存在问题;消除它并使用基本的csv功能:
writer = csv.writer(.....)
for d in dictrows:
row = [d[fieldname] for fieldname in fieldnames]
writer.writerow(row)