J'ai un dictionnaire sous la forme suivante:
[{'variable1': a1, 'variable2':a2, 'variable3': a3}, {'variable1': b1, 'variable2':a2, 'variable3': a3}, ...]
(Il y a n entrées dans ce dictionnaire).
J'ai un problème où je veux obtenir toutes les combinaisons possibles des différentes valeurs, par exemple:
[(a1, a2, a3), (b1, a2, a3), (c1, a2, a3), (a1, b2, a3), ...]
Je sais que cela peut être fait avec un produit cartésien avec itertools code>. Cependant, j'ai remarqué que mon problème serait beaucoup plus facile si le résultat était sous la forme suivante:
{
'variable_1': [a1, b1, c1],
'variable_2': [a2, b2, c2],
'variable_3': [a3, b3, c3],
...
}
Y a-t-il un moyen simple de le faire?
p>
3 Réponses :
[{'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'a3', 'variable_4': 'a3'}, {'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'a3', 'variable_4': 'b3'}, {'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'a3', 'variable_4': 'c3'}, {'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'a3', 'variable_4': 'd4'}, ...]
Vous aurez encore besoin de itertools.product pour cela:
>>> dict([('v1', 1), ('v2', 3)])
{'v1': 1, 'v2': 3}
>>> zip(['v1', 'v2'], [1, 3])
[('v1', 1), ('v2', 3)]
Vous pouvez lire le générateur comme suit de droite à gauche:
* s'appelle l'opérateur splat ): >>> list(itertools.product(*a.values())) [(1, 3), (1, 4), (2, 3), (2, 4)]
zip pour créer des paires de clés et le résultat du produit. >>> list(gen)
[{'v1': 1, 'v2': 3}, {'v1': 1, 'v2': 4}, {'v1': 2, 'v2': 3}, {'v1': 2, 'v2': 4}]
a = {'v1': [1,2], 'v2': [3,4]}
gen = (dict(zip(a.keys(), x)) for x in itertools.product(*a.values()))
Vous pouvez également utiliser une fonction récursive pour une solution sans importation:
[{'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'a3'}, {'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'b3'}, {'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'c3'}, {'variable_1': 'a1', 'variable_2': 'b2', 'variable_3': 'a3'}, {'variable_1': 'a1', 'variable_2': 'b2', 'variable_3': 'b3'}, {'variable_1': 'a1', 'variable_2': 'b2', 'variable_3': 'c3'}, {'variable_1': 'a1', 'variable_2': 'c2', 'variable_3': 'a3'}, {'variable_1': 'a1', 'variable_2': 'c2', 'variable_3': 'b3'}, {'variable_1': 'a1', 'variable_2': 'c2', 'variable_3': 'c3'}, {'variable_1': 'b1', 'variable_2': 'a2', 'variable_3': 'a3'}, {'variable_1': 'b1', 'variable_2': 'a2', 'variable_3': 'b3'}, {'variable_1': 'b1', 'variable_2': 'a2', 'variable_3': 'c3'}, {'variable_1': 'b1', 'variable_2': 'b2', 'variable_3': 'a3'}, {'variable_1': 'b1', 'variable_2': 'b2', 'variable_3': 'b3'}, {'variable_1': 'b1', 'variable_2': 'b2', 'variable_3': 'c3'}, {'variable_1': 'b1', 'variable_2': 'c2', 'variable_3': 'a3'}, {'variable_1': 'b1', 'variable_2': 'c2', 'variable_3': 'b3'}, {'variable_1': 'b1', 'variable_2': 'c2', 'variable_3': 'c3'}, {'variable_1': 'c1', 'variable_2': 'a2', 'variable_3': 'a3'}, {'variable_1': 'c1', 'variable_2': 'a2', 'variable_3': 'b3'}, {'variable_1': 'c1', 'variable_2': 'a2', 'variable_3': 'c3'}, {'variable_1': 'c1', 'variable_2': 'b2', 'variable_3': 'a3'}, {'variable_1': 'c1', 'variable_2': 'b2', 'variable_3': 'b3'}, {'variable_1': 'c1', 'variable_2': 'b2', 'variable_3': 'c3'}, {'variable_1': 'c1', 'variable_2': 'c2', 'variable_3': 'a3'}, {'variable_1': 'c1', 'variable_2': 'c2', 'variable_3': 'b3'}, {'variable_1': 'c1', 'variable_2': 'c2', 'variable_3': 'c3'}]
Sortie:
def combo(data, c=[]):
if not data:
yield c
else:
for i in data[0]:
yield from combo(data[1:], c+[i])
d = {'variable_1': ['a1', 'b1', 'c1'], 'variable_2': ['a2', 'b2', 'c2'], 'variable_3': ['a3', 'b3', 'c3']}
keys, values = zip(*d.items())
result = [dict(zip(keys, i)) for i in combo(values)]
Utilisez
itertools.productpuis transformez les tuples qu'il renvoie en dictionnaires?