我正在尝试加载对于json.load
. 我花了一段时间研究了ijson
许多堆栈溢出帖子,并使用了以下代码,大部分是从https://stackoverflow.com/a/58148422/11357695窃取的:
def extract_json(filename):
listJ=[]
with open(filename, 'rb') as input_file:
jsonobj = ijson.items(input_file, 'records.item', use_float=True)
jsons = (o for o in jsonobj)
for j in jsons:
listJ.append(j)
return listJ
我的 JSON 文件作为 dict 读入,有 6 个键,其中一个是'records'
. 上述函数仅复制此'records'
键值的内容。我对此进行了更多研究,并得出ijson.items
使用前缀 ( 'records.item'
) 的结论。所以它只是复制这个键的值也就不足为奇了。但我想得到一切。
为了实现这一点,我查看了 usingijson.parse
来给出前缀列表。当我将parser
下面奇怪的生成器对象生成的所有前缀输入到ijson.items()
使用迭代循环中时,我MemoryError
很快就从json.items()
语句中得到了一个。我还获得IncompleteJSONError
了代码的早期迭代,当前版本没有出现。但是,如果我删除该except ijson.IncompleteJSONError
语句,我会得到Memory Error
:
def loadBigJsonBAD(filename):
with open(filename, 'rb') as input_file:
parser = ijson.parse(input_file)
prefixes=[]
for prefix , event, value in parser:
prefixes.append(prefix)
listJnew=[]
with open(filename, 'rb') as input_file:
for prefix in prefixes:
jsonobjn = ijson.items(input_file, prefix, use_float=True)
try:
jsonsn = (o for o in jsonobjn)
for jn in jsonsn:
listJnew.append(jn)
except ijson.IncompleteJSONError:
continue
return listJnew
我尝试了如果我只搜索没有 的前缀会发生什么'record'
,看看这是否至少会给我字典的其余部分。但是,它实际上工作得很好,并创建了一个列表,其第一个对象与生成的对象相同json.load
(在这种情况下它工作,因为我使用一个小文件来测试代码):
def loadBigJson(filename):
with open(filename, 'rb') as input_file:
parser = ijson.parse(input_file)
prefixes=[]
for prefix , event, value in parser:
if prefix[0:len('records')] != 'records':
prefixes.append(prefix)
listJnew=[]
with open(filename, 'rb') as input_file:
for prefix in prefixes:
jsonobjn = ijson.items(input_file, prefix, use_float=True)
try:
jsonsn = (o for o in jsonobjn)
for jn in jsonsn:
listJnew.append(jn)
except ijson.IncompleteJSONError:
continue
return listJnew
测试时:
path_json=r'C:\Users\u03132tk\.spyder-py3\antismashDB\GCF_010669165.1\GCF_010669165.1.json'
extractedJson=extract_json(path_json) #extracts the 'records' key value
loadedJson=json.load(open(path_json, 'r')) #extracts entire json file
loadedJsonExtracted=loadedJson['records'] #the thing i am using to compare to the extractedJson item
bigJson=loadBigJson(path_json) #a list whose single object is the same as loaded json.
print (bigJson[0]==loadedJson)#True
print (bigJson[0]['records']==loadedJsonExtracted)#True
print (bigJson[0]['records']==extractedJson)#True
这很好,但它强调我并不真正了解发生了什么 - 为什么records
该函数需要前缀extract_json
(我尝试了 json 字典中的其他键,没有命中)但适得其反loadBigJson
?是什么生成了错误语句,为什么except IncompleteJSONError
语句会阻止MemoryError
?
如您所知,我对使用 JSON 非常不熟悉,因此任何一般性提示/说明也会很棒。
感谢您阅读小说,即使您没有答案!
蒂姆