Combinación de diccionarios anidados con longitudes arbitrarias en Python.
Estoy buscando una función que tome un diccionario anidado y produzca las combinaciones/producto de los valores.
Mi consulta es similar al problema especificado aquí, pero no puedo adaptar las respuestas para que se ajusten a mis necesidades:
https://stackoverflow.com/questions/50606454/cartesian-product-of-nested-dictionaries-of-lists
Deseo tener una entrada como esta:
d = {
"country": [1, 2],
"health_state": [
{"healthy": [1]},
{"breast cancer": {"stage": [1, 2]}}
]
}
Producir una salida como sigue:
[
{{"country":1},{"health state":{"healthy":1}}},
{{"country":2},{"health state":{"healthy":1}}},
{{"country":1},{"health state":{"breast cancer":{"stage":1}}}},
{{"country":1},{"health state":{"breast cancer":{"stage":2}}}},
{{"country":2},{"health state":{"breast cancer":{"stage":1}}}},
{{"country":2},{"health state":{"breast cancer":{"stage":2}}}}
]
En este ejemplo, la salida es una lista de ‘estados’ que una persona puede ocupar.
- Cualquier dos elementos de una lista (entrada) no deben estar en el mismo elemento de la lista devuelta (salida), por ejemplo, alguien no puede estar en el país 1 y país 2 simultáneamente.
- Todas las claves en un diccionario (entrada) deben ser devueltas en el mismo elemento de la lista (salida), por ejemplo, alguien está en el país 1 y también en un estado de salud. Si ese estado de salud es ‘cáncer de mama’, también está en la etapa 1 o en la etapa 2.
Puedo imaginar una solución que requiere muchos bucles for, verificando si los elementos son diccionarios, listas o ninguno, pero esto parece ineficiente, especialmente para diccionarios profundamente anidados. Sospecho que hay una solución más elegante utilizando itertools.product
y recursión, tal vez?
davy.ai
Para obtener la salida deseada a partir del diccionario anidado de entrada, necesitamos realizar un producto cartesiano de todos los valores en cada clave del diccionario (excluyendo cualquier diccionario anidado). Para los diccionarios anidados, necesitamos llamar a la función de producto cartesiano de forma recursiva hasta que alcancemos el nivel más interno.
Aquí hay una función que logra esta tarea:
Para usar esta función con el diccionario de entrada
d
, simplemente llamamosdict_product(d)
.Esto devolverá la salida siguiente:
Esta salida coincide con la salida deseada especificada en la pregunta.