I have to do this regularly in coding my studies. You will want to use the defaultdict package because it allows you to add key: value pairs at any level with a simple purpose. I will show you after answering your question. This comes directly from one of my programs. Focus on the last 4 lines (these are not comments) and see how the variables are saved in the rest of the block to see what it does:
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 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
Here is the digest.
- Firstly, for the n-level dictionary you need to sort and dump everything into a list of (n + 1) -strings in the form [key_1, key_2, ..., key_n, value].
- Then, to initialize the n-level dictionary, you simply type "defaultdict (lambda:" (minus quotation marks) n-1 times, stick "defaultdict (list)" (or some other data type) at the end and close the parentheses.
- Add to list with for loop. * Note: when you go to access data values ββat the lowest level, you probably have to type my_dict [key_1] [key_2] [...] [key_n] [0] to get actual values, not just data descriptions type.
- * Edit: when your dictionary is as important as you want it, set default_factory - None.
If you did not set default_factory to None, you can add your nested dictionary later by typing something like my_dict [key_1] [key_2] [...] [new_key] = new_value or using the append () command. You can even add additional dictionaries if the ones you add on these assignment forms are not nested by yourself.
* WARNING! The recently added last line of this code snippet in which you set the default_factory attribute to None is very important. Your computer should know when you finish adding to the dictionary, otherwise it may continue to allocate memory in the background to prevent buffer overflows, waiting for the program to stop. This is a type of memory leak . I learned this hard way after I wrote this answer. This problem bothered me for several months, and I donβt even think that I was the one who understood this at the end, because I didnβt understand anything about memory allocation.