我有一个装满文件的文件夹。我需要加载这些文件并重建嵌套字典。文件名包括字典的结构。例如,一个文件名为“vz_ERA_Neural_Water_Forecast.npy”。 “vz”是原始字典名称,“ERA”是第一个键,“Neural”是第二个键,依此类推。有些文件仅嵌套 3 层,有些则嵌套 5 层。
这是我尝试过的代码:
# Get list of all the files to load
files = os.listdir(Path(fc.selected,'vz_save'))
# remove from list name of file that contains files we care about and hidden files
files.remove('fileNamesAndTypes.txt')
for file in files:
if file.startswith('.'):
files.remove(file)
# creat an empty dictionary in which to eventually allocate the loaded files
vz_check = {}
for file in files:
#print(file)
ext = Path(file).suffix
fileNoExt = Path(file).stem # remove the file extension (file type)
keys = fileNoExt.split('_')
keys.remove('vz')
# find matching fileNoExt to value in fileNamesAndTypes[key]
reloadedType = fileNamesAndTypes_check[fileNoExt]
# load the file?
if reloadedType == str:
#print(f"type=str; reloadedType={reloadedType}")
reload = open(Path(fc.selected,'vz_save',file),'rb')
contents = reload.read()
print(contents)
for key in reversed(keys):
vz_check = {key: vz_check}
elif reloadedType == xr.core.dataset.Dataset:
#print(f"type=xr.core.dataset.Dataset; reloadedType={reloadedType}")
elif reloadedType == xr.core.dataarray.DataArray:
#print(f"type=xr.core.dataarray.DataArray; reloadedType={reloadedType}")
elif reloadedType == int:
#print(f"type=int; reloadedType={reloadedType}")
elif reloadedType == list:
#print(f"type=list; reloadedType={reloadedType}")
elif reloadedType == np.ndarray:
#print(f"type=np.ndarray; reloadedType={reloadedType}")
我最终得到的是一个非常丑陋的超级嵌套,每个级别只有一行越来越深的单一键,而不是每个级别都有多个键。
如何让它自动加载所有嵌套零件并将其缝合在一起。有没有更好的方法来解决这个问题?
编辑:
在等待帮助的过程中,我想出了这个解决方案,我觉得它非常丑陋,但会完成工作。必须有更好的方法来做到这一点。
def buildDict(keyss,contentss,theDict):
if len(keyss) == 1:
theDict = {keyss: contentss}
elif len(keyss) == 2:
theDict = {keyss[0] : { keyss[1] : contentss } }
elif len(keyss) == 3:
theDict = {keyss[0] : {keyss[1] : {keyss[2] : contentss } } }
elif len(keyss) == 4:
theDict = {keyss[0] : {keyss[1] : {keyss[2] : {keyss[3] : contentss } } } }
elif len(keyss) == 5:
theDict = {keyss[0] : {keyss[1] : {keyss[2] : {keyss[3] : {keyss[4] : contentss } } } } }
这是解决方案。
因为我知道字典 vz 应该是什么样子,所以我只是将其预设为结构并使用下面的代码来填充空白。目前它仅适用于“reloadedType == str”,但其余的应该相对容易理解。我确信有更好的方法,但这行得通。
# load the individual files and reconstruct the dictionary
vz_reloaded = {
key1: {
key2: {
sub_key: [] for sub_key in [
'Reof', 'Training_Data', 'Filetype', 'Polarization',
'Coeffs', 'Modes', 'Models', 'Score', 'RMSE', 'Reof_forecast', 'Input_Images',
'Reof_hindcast', 'Hindcast', 'Forecast', 'Best_Index', 'Difference',
'Water_Hindcast', 'Water_Forecast'
]
}
for key2 in ['Polynomial', 'Neural']
}
for key1 in ['Q', 'ERA']
}
# Get list of all the files to load
files = os.listdir(Path(fc.selected,'vz_save'))
# remove from list name of file that contains files we care about and hidden files
files.remove('fileNamesAndTypes.txt')
for file in files:
if file.startswith('.'):
files.remove(file)
# creat an empty dictionary in which to eventually allocate the loaded files
vz_reloaded = {}
for file in files:
#print(file)
ext = Path(file).suffix
fileNoExt = Path(file).stem # remove the file extension (file type)
keys = fileNoExt.split('_')
keys.remove('vz')
# find matching fileNoExt to value in fileNamesAndTypes[key]
reloadedType = fileNamesAndTypes_check[fileNoExt]
# load the file?
if reloadedType == str:
#print(f"type=str; reloadedType={reloadedType}")
reload = open(Path(fc.selected,'vz_save',file),'rb')
contents = reload.read()
elif reloadedType == xr.core.dataset.Dataset:
#print(f"type=xr.core.dataset.Dataset; reloadedType={reloadedType}")
pass
elif reloadedType == xr.core.dataarray.DataArray:
#print(f"type=xr.core.dataarray.DataArray; reloadedType={reloadedType}")
pass
elif reloadedType == int:
#print(f"type=int; reloadedType={reloadedType}")
pass
elif reloadedType == list:
#print(f"type=list; reloadedType={reloadedType}")
pass
elif reloadedType == np.ndarray:
#print(f"type=np.ndarray; reloadedType={reloadedType}")
pass
# Here's the part that puts the pieces of the dictionary back in.
try:
if len(keys)==3:
vz_reloaded[keys[0]][keys[1]][keys[2]] = contents
elif len(keys)==4:
vz_reloaded[keys[0]][keys[1]][keys[2]][keys[3]] = contents
elif len(keys)==5:
vz_reloaded[keys[0]][keys[1]][keys[2]][keys[3]][keys[4]] = contents
except:
print(f"This key set is a problem: {keys}")
print(f"Type: {reloadedType}")