exec语句内存错误

1 投票
2 回答
1134 浏览
提问于 2025-04-18 11:13

我有一个很大的字典文本文件,它的样子是这样的:

{"0_3":[(80.10858194902539,-175.29917925596237,1)   ],"10_10":[(50.610770881175995,-57.17018913477659,1)    , (52.946319971233606,-66.9017181918025,1)].........}

这个文件大约有138MB,我需要在我的Python代码中使用这个字典并访问里面的值。所以,我有以下这段代码(diction.txt是文件名,我想把字典放到我的spots变量里):

with open("diction.txt","r") as myfile:
    data = myfile.read().replace('\n','')

exec("spots = " + data)

但是,当我运行这段代码时,出现了内存错误。我不确定这是因为文件太大还是其他原因。如果是文件大小的问题,我该怎么解决呢?

谢谢你的帮助!

补充: 解决方案:

根据@DrV在评论中提到的解决办法,我需要去掉文件中的括号,因为JSON格式不识别元组,使用以下代码:

import json 

with open("diction.txt","r") as myfile:
    data = myfile.read().replace('\n','').replace('(','').replace(')','')
spots = json.loads(data)

然后,我还需要修改我代码的其他部分,以适应我把格式从元组改为连续列表的变化。

2 个回答

2

听起来你可能只需要这样做:

with open("diction.txt","r") as myfile:
    data = json.load(myfile)

这可能会出现一些错误……具体情况不好说……不过如果你能把大文件转换成json格式,那可能会有很大帮助。

6

使用 execeval 这两个东西总是有点危险,最好还是避免使用。看起来你的数据结构可以用下面的方式来处理:

import ast

with open("diction.txt","r") as myfile:
    data = myfile.read().replace('\n','')

mydata = ast.literal_eval(data)

这里的区别在于 ast.literal_eval 不把你的数据当成程序代码,而是当成普通数据来处理。这个过程要轻便得多,也更安全。

不过,有些人也反映使用 ast.literal_eval 时遇到了一些问题。它的复杂程度还是超出了你的需求:

用 ast.literal_eval 加载 41MB 的文件会导致内存错误

如果你有可能把文件格式改成符合 JSON 的格式,那你就可以使用 json 模块来读写它。毕竟,JSON 数据比 Python 字典的转储更常见。你的数据看起来除了使用元组外,其实是符合 JSON 格式的。如果把元组改成列表,你就可以顺利进行下去了。

想了解更多关于这些选项的讨论,可以看看:

python eval vs ast.literal_eval vs JSON decode

如果你最终使用 JSON(而且很可能会这样),有不同的库可以选择。如果标准的 Python json 在解码时速度太慢,你可以使用比如 ujson,它被宣传为非常快。

撰写回答