Python被杀(可能是内存泄漏)

时间:2013-07-20 19:57:30

标签: python

我已经研究了几个星期了,我已经阅读了很多关于python内存泄漏的问题,但我无法弄明白。

我有一个包含大约700万行的文件。对于每一行,我需要创建一个字典。所以这是一个字典列表,如下所示:

[{'a': 2, 'b':1}{'a':1, 'b':2, 'c':1}]

我在做什么......

list = []
for line in file.readlines():
    terms = line.split(" ")
    dict = {}
    for term in terms:
        if term in dict:
            dict[term] = dict[term] + 1
        else:
            dict[term] = 1
    list.append(dict.copy())
    dict.clear()
file.close()

问题在于,当我运行它时,它总是在6000000行左右被杀死。最初我只是做dict = {}但改变它所以我在阅读类似帖子后做dict.clear(),但它没有改善任何东西。我知道一些关于循环引用的帖子,我查看了我的代码,但我不认为我有这个问题。

我怀疑在列表中存储700万个字典无法用Python处理?我很感激任何关于如何在不被杀害的情况下完成所有事情的建议。

(版本是2.7.4)

2 个答案:

答案 0 :(得分:8)

尝试:

from collections import Counter
with open('input') as fin:
    term_counts = [Counter(line.split()) for line in fin]

我相信这是您尝试使用代码实现的目标。

这样可以避免.readlines()首先将文件加载到内存中,利用Counter进行计数并一次性构建列表,而无需在消隐/分配/清除字典/附加到列表之间进行操作。

答案 1 :(得分:1)

由于python使用至少中途正常的垃圾收集,所以你无法用一段代码来解决内存泄漏问题。一个潜在的问题是你可能内存不足(所以绝对要避免使用.readlines为starters;使用“for my in my_file”代替);由于各种原因,字典实际上使用了相当多的内存 - 一个是字典故意使用比实际当前密钥集大得多的哈希表,既有助于缓解冲突,又能够快速添加很多内容如果需要,可以使用新密钥,每次插入可以分摊O(1)个时间。由于你在文件结束之前已经接近文件的末尾,你可以尝试将最终的dict存储为2元组的k元组,其中第一个k元组包含你想要存储的k个元组,第二个k元组是k键的k计数。这应该节省一些内存,代价是为了在你的一个2元组中查找my_key,你需要做类似的事情:

match_idx = [i for i in xrange(len(T[0])) if T[0][i] == my_key]
if len(match_idx) == 0:
  # no match, do whatever
else: #match
  count = T[1][match_idx[0]] 
  # now do whatever with count

查找的运行时间将是您必须搜索的键的数量是线性的,而不是恒定的时间(尽管请注意,执行字典查找的散列不是一个简单的操作,因此常量是对于更简单的操作,大于典型常数)。如果你按照排序的顺序存储你的密钥,那么你可以使用二进制搜索来快速找到你的密钥,但这需要更多的代码,我假设你正在使用python,因为它往往会提供短代码。但是,如果您已经成功创建了600万个词典,那么平均而言,您的700万个词典中必须没有多个键。因此,如果您真的想将python用于数据集,除非您获得具有更多内存的计算机,否则这可能是唯一的方法之一。

相关问题