我必须在为我的研究编写代码时经常这样做。您将希望使用defaultdict包,因为它允许您添加键:值对在任何级别上,通过简单的分配。回答完你的问题我会给你看的。这是直接来源于我的一个程序。关注最后4行(不是注释)并在块的其余部分跟踪变量,看看它在做什么:from astropy.io import fits #this package handles the image data I work with
import numpy as np
import os
from collections import defaultdict
klist = ['hdr','F','Ferr','flag','lmda','sky','skyerr','tel','telerr','wco','lsf']
dtess = []
for file in os.listdir(os.getcwd()):
if file.startswith("apVisit"):
meff = fits.open(file, mode='readonly', ignore_missing_end=True)
hdr = meff[0].header
oid = str(hdr["OBJID"]) #object ID
mjd = int(hdr["MJD5"].strip(' ')) #5-digit observation date
for k,v in enumerate(klist):
if k==0:
dtess = dtess+[[oid,mjd,v,hdr]]
else:
dtess=dtess+[[oid,mjd,v,meff[k].data]]
#header extension works differently from the rest of the image cube
#it's not relevant to populating dictionaries
#HDUs in order of extension no.: header, flux, flux error, flag mask,
# wavelength, sky flux, error in sky flux, telluric flux, telluric flux errors,
# wavelength solution coefficients, & line-spread function
dtree = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
for s,t,u,v in dtess:
dtree[s][t][u].append(v)
#once you've added all the keys you want to your dictionary,
#set default_factory attribute to None
dtree.default_factory = None
这是摘要版本。在首先,对于一个n级字典,必须进行排序和转储
所有内容都以[key_1,key_2,
... ,键\n,值]。在
然后,要初始化n级字典,
只需输入“defaultdict(lambda:”(减去引号)n-1次,
在末尾粘贴“defaultdict(list)”(或其他数据类型),然后
关闭括号。在
用for循环附加到列表。*注意:当您访问数据值时
你可能会有最低档的U键
[…][key_n][0]获取实际值,而不仅仅是数据的描述
在其中键入。在
*编辑:当你的字典足够大的时候,设置
默认的“工厂”属性为“无”。在
如果尚未将default_factory设置为None,则可以稍后通过键入my_dict[key_1][key_2][…][new_key]=new_value,或使用append()命令来添加到嵌套字典中。您甚至可以添加额外的字典,只要您通过这些赋值形式添加的字典本身不是嵌套的。在
在*
警告!该代码段中新添加的最后一行(在该行中,您将default_factory属性设置为None)是super important。你的电脑需要知道你什么时候完成了字典的添加,否则它可能会继续在后台分配内存以防止buffer overflow,耗尽你的内存,直到程序停止运行。这是memory leak的类型。在我写下这个答案后的一段时间里,我艰难地学会了这一点。这个问题困扰了我几个月,我甚至不认为我是最终解决它的人,因为我对内存分配一无所知。在