问题
Consider a nested dictionary:
d1 = {'key': {'r1': [1,2,3],
'r2': [5,6]} }
I want to extract a list of dictionaries from the above dict which takes all combinations of the nested dictionary's list items. For example, for the above dict, I would want this:
ans = [ {'root': 'key', 'r1': 1, 'r2':5},
{'root': 'key', 'r1': 1, 'r2':6},
{'root': 'key', 'r1': 2, 'r2':5},
{'root': 'key', 'r1': 2, 'r2':6},
{'root': 'key', 'r1': 3, 'r2':5},
{'root': 'key', 'r1': 3, 'r2':6}
]
I can do this manually for the above example but the issue is that the number of keys apart from 'root' in d1 could be any variable number and my answer would change, for eg, consider:,
d2 = {'key': {'r1': [1,2,3],
'r2': [5,6],
'r3': [7,8]}
}
Now the answer would look like:
ans = [ {'root': 'key', 'r1': 1, 'r2':5, 'r3':7},
{'root': 'key', 'r1': 1, 'r2':6, 'r3':8},
{'root': 'key', 'r1': 2, 'r2':5, 'r3':7},
{'root': 'key', 'r1': 2, 'r2':6 ,'r3':8},
.
.(total 12 combinations)
]
I can use the itertools.product to find combinations of items in variable number of lists as following:
from itertools import product
list(product(d1['key']['r1'], d1['key']['r2']))
returns:
[(1, 5), (1, 6), (2, 5), (2, 6), (3, 5), (3, 6)]
But how can I add the corresponding keys to each of these items and how can I do this dynamically?
回答1:
As long as the "root" is unchanging, you can use itertools.product
and zip
each product with the dictionary keys:
>>> from itertools import product
>>> combinations = product(*d2['key'].values())
>>> [{'root': 'key', **dict(zip(d2['key'].keys(), c))} for c in combinations]
[{'r1': 1, 'r2': 5, 'r3': 7, 'root': 'key'},
{'r1': 1, 'r2': 5, 'r3': 8, 'root': 'key'},
{'r1': 1, 'r2': 6, 'r3': 7, 'root': 'key'},
{'r1': 1, 'r2': 6, 'r3': 8, 'root': 'key'},
...
Thankfully, dict.keys()
and dict.values()
return the keys and values in their corresponding order, regardless of your python version, this is guaranteed by the spec.
来源:https://stackoverflow.com/questions/52799742/how-to-find-combinations-of-lists-from-nested-dictionaries