在Python中处理文件时出现内存错误

在Python中处理文件时出现内存错误,python,Python,我打算根据每行中的键将一个总共约500MB的文件读入dict。代码片段如下所示: f2 = open("ENST-NM-chr-name.txt", "r") # small amount lines = [l.strip() for l in f2.readlines() if l.strip()] sample = dict([(l.split("\t")[2].strip("\""), l) for l in lines]) ## convert [(1,2), (3,4)] t

我打算根据每行中的键将一个总共约500MB的文件读入dict。代码片段如下所示:

f2 = open("ENST-NM-chr-name.txt", "r")   # small amount
lines = [l.strip() for l in f2.readlines() if l.strip()]
sample = dict([(l.split("\t")[2].strip("\""), l) for l in lines])    ## convert [(1,2), (3,4)] to {1:2, 3:4}
在内存为4GB的机器上运行时,python会抱怨内存错误。如果我将
sample
变量的求值表达式更改为
[l表示行中的l]
,则效果良好

起初,我认为这是由于
split
方法消耗了大量内存,因此我将代码调整为:

def find_nth(haystack, needle, n):
    start = haystack.find(needle)
    while start >= 0 and n > 1:
        start = haystack.find(needle, start+len(needle))
        n -= 1
    return start

...

sample = dict([(l[find_nth(l, "\t", 4):].strip(), l) for l in lines])
但结果是一样的

一个新的发现是,只要我删除
dict()
转换,不管代码逻辑如何,它都可以在没有OOM的情况下正常运行


有人能给我一些关于这个问题的想法吗?

如果你把你的列表变成一个生成器,把你的口述变成一个可爱的字典理解力,会怎么样

f2 = open("ENST-NM-chr-name.txt", "r")   # small amount
lines = (l.strip() for l in f2 if l.strip())
sample = {line.split('\t')[2].strip('\"'): line for line in lines}
上面的第2行被误认为是
Line=(f2中的l的l.strip()。如果l.strip(),则为readlines())


生成器和听写理解是否(以某种方式)减轻了记忆需求?

如果您将列表变成生成器,并将听写变成可爱的词典理解,会怎么样

f2 = open("ENST-NM-chr-name.txt", "r")   # small amount
lines = (l.strip() for l in f2 if l.strip())
sample = {line.split('\t')[2].strip('\"'): line for line in lines}
上面的第2行被误认为是
Line=(f2中的l的l.strip()。如果l.strip(),则为readlines())


生成器和听写理解是否(以某种方式)减轻了记忆需求?

如果您将列表变成生成器,并将听写变成可爱的词典理解,会怎么样

f2 = open("ENST-NM-chr-name.txt", "r")   # small amount
lines = (l.strip() for l in f2 if l.strip())
sample = {line.split('\t')[2].strip('\"'): line for line in lines}
上面的第2行被误认为是
Line=(f2中的l的l.strip()。如果l.strip(),则为readlines())


生成器和听写理解是否(以某种方式)减轻了记忆需求?

如果您将列表变成生成器,并将听写变成可爱的词典理解,会怎么样

f2 = open("ENST-NM-chr-name.txt", "r")   # small amount
lines = (l.strip() for l in f2 if l.strip())
sample = {line.split('\t')[2].strip('\"'): line for line in lines}
上面的第2行被误认为是
Line=(f2中的l的l.strip()。如果l.strip(),则为readlines())


生成器和dict理解是否(以某种方式)减轻了内存需求?

您正在创建一个包含每一行的列表,该列表将继续存在,直到
行超出范围,然后在此基础上创建另一个完全不同的字符串的大列表,然后在内存耗尽之前,将其清除。只需一步构建
dict

with open("ENST-NM-chr-name.txt") as f:
    sample = {}

    for l in f:
        l = l.strip()

        if l:
            sample[l.split("\t")[2].strip('"')] = l

通过使用生成器表达式而不是列表理解,您可以实现大致相同的效果,但(对我来说)感觉更好的是不要两次
剥离

您创建了一个包含每一行的列表,它将继续存在,直到
超出范围,然后在它的基础上创建另一个完全不同的字符串的大列表,然后在它耗尽内存之前,从中删除一个
dict
。只需一步构建
dict

with open("ENST-NM-chr-name.txt") as f:
    sample = {}

    for l in f:
        l = l.strip()

        if l:
            sample[l.split("\t")[2].strip('"')] = l

通过使用生成器表达式而不是列表理解,您可以实现大致相同的效果,但(对我来说)感觉更好的是不要两次
剥离

您创建了一个包含每一行的列表,它将继续存在,直到
超出范围,然后在它的基础上创建另一个完全不同的字符串的大列表,然后在它耗尽内存之前,从中删除一个
dict
。只需一步构建
dict

with open("ENST-NM-chr-name.txt") as f:
    sample = {}

    for l in f:
        l = l.strip()

        if l:
            sample[l.split("\t")[2].strip('"')] = l

通过使用生成器表达式而不是列表理解,您可以实现大致相同的效果,但(对我来说)感觉更好的是不要两次
剥离

您创建了一个包含每一行的列表,它将继续存在,直到
超出范围,然后在它的基础上创建另一个完全不同的字符串的大列表,然后在它耗尽内存之前,从中删除一个
dict
。只需一步构建
dict

with open("ENST-NM-chr-name.txt") as f:
    sample = {}

    for l in f:
        l = l.strip()

        if l:
            sample[l.split("\t")[2].strip('"')] = l


通过使用生成器表达式而不是列表理解,您可以获得大致相同的效果,但是(对我来说)不必两次剥离
感觉更好。

在这个网站上的某个地方,有一个问题是
dict
需要多少内存,这比你想象的要多得多。你能给出与你提到的内容相关的特定URL链接吗?谢谢@马克·兰索米如果我能记住,我早就记住了。对不起。另外,你正在阅读标签分隔值吗?在这个网站的某个地方有一个问题,关于一个
dict
需要多少内存,这比你预期的要多得多。你能给出与你提到的内容相关的特定URL链接吗?谢谢@马克·兰索米如果我能记住,我早就记住了。对不起。另外,你正在阅读标签分隔值吗?在这个网站的某个地方有一个问题,关于一个
dict
需要多少内存,这比你预期的要多得多。你能给出与你提到的内容相关的特定URL链接吗?谢谢@马克·兰索米如果我能记住,我早就记住了。对不起。另外,你正在阅读标签分隔值吗?在这个网站的某个地方有一个问题,关于一个
dict
需要多少内存,这比你预期的要多得多。你能给出与你提到的内容相关的特定URL链接吗?谢谢@马克·兰索米如果我能记住,我早就记住了。抱歉。另外,您正在读取制表符分隔的值吗?我删除了显式
r
模式,因为这是默认模式。我同意不要重复
strip
。另一个选项是执行
map(str.strip,f)
(在Python 3中)或
itertools.imap(…)
(在Python 2中)。我删除了显式
r
模式,因为它是默认模式。我同意不要重复
strip
。另一个选项是执行
map(str.strip,f)
(在Python 3中)或
itertools.imap(…)
(在Python 2中)。我删除了显式
r
模式,因为它是默认模式。我同意不要重复
strip
。另一个选项是执行
map(str.strip,f)
(在Python 3中)或