Я прошу вас помочь, чтобы решить проблему, когда я теряю сознание с 3-х дней.Рекурсия Python с dicts
Это довольно трудно объяснить, но я пытаюсь преобразовать этот Dict:
{
'contrats': [
{
'code': '1234567890',
'produits': [
{
'code': 'MAGENTA',
},
{
'code': 'EMERAUDE',
},
],
'familles': [
{
'code': 'FAMILLE_KLEIN',
'personnes': [
{
'code': 'MR_KLEIN',
'nom': 'KLEIN',
'prenom': 'Monsieur',
'date_naissance': '01/01/1973',
'role_famille': 'A',
'roles_contrat': ['A', 'S', 'P'],
},
{
'code': 'MME_KLEIN',
'nom': 'KLEIN',
'prenom': 'Madame',
'date_naissance': '01/01/1976',
'role_famille': 'C',
'roles_contrat': ['C'],
},
{
'code': 'E1_KLEIN',
'nom': 'KLEIN',
'prenom': 'Enfant 1',
'date_naissance': '01/01/1998',
'role_famille': 'E',
'roles_contrat': ['E'],
},
{
'code': 'E2_KLEIN',
'nom': 'KLEIN',
'prenom': 'Enfant 2',
'date_naissance': '01/01/2001',
'role_famille': 'E',
'roles_contrat': ['E'],
},
],
},
],
},
],
}
В этом Словаре:
[
{
'contrat_code': '1234567890',
'produit_code': 'MAGENTA',
'famille_code': 'FAMILLE_KLEIN',
'personne_code': 'MR_KLEIN',
'personne_nom': 'KLEIN',
'personne_prenom': 'Monsieur',
'personne_date_naissance': '01/01/1973',
'personne_role_famille': 'A',
'personne_roles_contrat': ['A', 'S', 'P'],
},
{
'contrat_code': '1234567890',
'produit_code': 'EMERAUDE',
'famille_code': 'FAMILLE_KLEIN',
'personne_code': 'MR_KLEIN',
'personne_nom': 'KLEIN',
'personne_prenom': 'Monsieur',
'personne_date_naissance': '01/01/1973',
'personne_role_famille': 'A',
'personne_roles_contrat': ['A', 'S', 'P'],
},
{
'contrat_code': '1234567890',
'produit_code': 'MAGENTA',
'famille_code': 'FAMILLE_KLEIN',
'personne_code': 'MME_KLEIN',
'personne_nom': 'KLEIN',
'personne_prenom': 'Madame',
'personne_date_naissance': '01/01/1976',
'personne_role_famille': 'C',
'personne_roles_contrat': ['C'],
},
{
'contrat_code': '1234567890',
'produit_code': 'EMERAUDE',
'famille_code': 'FAMILLE_KLEIN',
'personne_code': 'MME_KLEIN',
'personne_nom': 'KLEIN',
'personne_prenom': 'Madame',
'personne_date_naissance': '01/01/1976',
'personne_role_famille': 'C',
'personne_roles_contrat': ['C'],
},
{
'contrat_code': '1234567890',
'produit_code': 'MAGENTA',
'famille_code': 'FAMILLE_KLEIN',
'personne_code': 'E1_KLEIN',
'personne_nom': 'KLEIN',
'personne_prenom': 'Enfant 1',
'personne_date_naissance': '01/01/1998',
'personne_role_famille': 'E',
'personne_roles_contrat': ['E'],
},
{
'contrat_code': '1234567890',
'produit_code': 'EMERAUDE',
'famille_code': 'FAMILLE_KLEIN',
'personne_code': 'E1_KLEIN',
'personne_nom': 'KLEIN',
'personne_prenom': 'Enfant 1',
'personne_date_naissance': '01/01/1998',
'personne_role_famille': 'E',
'personne_roles_contrat': ['E'],
},
{
'contrat_code': '1234567890',
'produit_code': 'MAGENTA',
'famille_code': 'FAMILLE_KLEIN',
'personne_code': 'E2_KLEIN',
'personne_nom': 'KLEIN',
'personne_prenom': 'Enfant 2',
'personne_date_naissance': '01/01/2001',
'personne_role_famille': 'E',
'personne_roles_contrat': ['E'],
},
{
'contrat_code': '1234567890',
'produit_code': 'EMERAUDE',
'famille_code': 'FAMILLE_KLEIN',
'personne_code': 'E2_KLEIN',
'personne_nom': 'KLEIN',
'personne_prenom': 'Enfant 2',
'personne_date_naissance': '01/01/2001',
'personne_role_famille': 'E',
'personne_roles_contrat': ['E'],
},
]
Как вы видите, , Мне нужно объединить все ключи/значения (контекст) t он диктует только на одном уровне.
У меня есть начало алгоритма, но он возвращает только 4 контекста вместо 8 ожидаемых.
def creer_contextes(contexte, sections, ctx=None, done=None):
resultats = []
ctx_local = (ctx or {}).copy()
vues = (done or set()).copy()
sections_ = set(aplatir(sections))
for section in sections_ - vues:
for element in contexte.get(section, []):
copie = element.copy()
normalisation = normaliser(copie, section[:-1], *sections_)
ctx_local.update(normalisation)
vues.add(section)
if vues == sections_:
resultats += [ctx_local.copy()]
if any(s in element.keys() for s in sections_):
resultats += creer_contextes(copie, sections, ctx=ctx_local, done=vues)
return resultats
def aplatir(ilist):
return sum(([x] if not isinstance(x, list) else aplatir(x) for x in ilist), [])
def normaliser(idict, clef, *excludes):
return {'{}_{}'.format(clef, key): value for key, value in idict.items() if key not in excludes}
Благодарим за предоставленную помощь!
Почему желание сделать это рекурсивно? Здесь ключи не могут быть просто закодированы? Ваша структура данных не подходит для рекурсивной обработки, у вас есть продукт из 4 списков, но они частично вложенные, частично смежные. –
И для правильного общего подхода вам нужно будет расширить свои префиксы ключей, чтобы включить иерархию; что, если в структуре есть вторая вложенная структура 'contrats'? –
И почему здесь исключается 'role_contrat'? Я ожидал бы большего умножения для каждого отдельного значения в этих списках. –