J'ai un dictionnaire aplati que je veux transformer en un dictionnaire imbriqué, de la forme suivante
flat = {'X_a_one': 10,
'X_a_two': 20,
'X_b_one': 10,
'X_b_two': 20,
'Y_a_one': 10,
'Y_a_two': 20,
'Y_b_one': 10,
'Y_b_two': 20}
Je veux le convertir sous la forme
nested = {'X': {'a': {'one': 10,
'two': 20},
'b': {'one': 10,
'two': 20}},
'Y': {'a': {'one': 10,
'two': 20},
'b': {'one': 10,
'two': 20}}}
La structure du dictionnaire plat est telle qu'il ne devrait pas y avoir de problèmes d'ambiguïté. Je veux que cela fonctionne pour des dictionnaires de profondeur arbitraire, mais les performances ne sont pas vraiment un problème. J'ai vu beaucoup de méthodes pour aplatir un dictionnaire imbriqué, mais pratiquement aucune pour imbriquer un dictionnaire aplati. Les valeurs stockées dans le dictionnaire sont soit des scalaires, soit des chaînes de caractères, jamais des itérables.
Jusqu'à présent, j'ai obtenu quelque chose qui peut prendre l'entrée
test_dict = {'X_a_one': '10',
'X_b_one': '10',
'X_c_one': '10'}
à la sortie
test_out = {'X': {'a_one': '10',
'b_one': '10',
'c_one': '10'}}
en utilisant le code
def nest_once(inp_dict):
out = {}
if isinstance(inp_dict, dict):
for key, val in inp_dict.items():
if '_' in key:
head, tail = key.split('_', 1)
if head not in out.keys():
out[head] = {tail: val}
else:
out[head].update({tail: val})
else:
out[key] = val
return out
test_out = nest_once(test_dict)
Mais j'ai du mal à trouver le moyen d'en faire quelque chose qui crée récursivement tous les niveaux du dictionnaire.
Toute aide serait appréciée !
(Quant à savoir pourquoi je veux faire ça : J'ai un fichier dont la structure est équivalente à un dict imbriqué, et je veux stocker le contenu de ce fichier dans le dictionnaire d'attributs d'un fichier NetCDF et le récupérer plus tard. Cependant, NetCDF ne vous permet que de mettre des dictionnaires plats comme attributs, donc je veux déflater le dictionnaire que j'ai précédemment stocké dans le fichier NetCDF).
9 votes
Question bien écrite.