我有以下字典:
intervals = {'param1': [0, 1],
'param2_hi': [4, 5, 6, 7, 8, 9],
'param2_lo': [0, 1, 2, 3, 4, 5],
'param3_hi': [9, 10, 11, 12, 13, 14, 15],
'param3_lo': [5, 6, 7, 8, 9, 10],
'param4': [0, 1],
'param5_hi': [4, 5, 6, 7, 8, 9],
'param5_lo': [0, 1, 2, 3, 4, 5]}
如何创建此词典的所有可能子集,其中我必须正好具有每个数字x中的一个用于' paramx'?这意味着我只能为param1(_lo或_hi)创建一个条目,为param2(_lo或_hi)创建一个条目,依此类推,并且每个子集必须包含没有_lo或_hi的每个param。
以下是两个可能的子集:
subset_one = {'param1': [0, 1],
'param2_hi': [4, 5, 6, 7, 8, 9],
'param3_hi': [9, 10, 11, 12, 13, 14, 15],
'param4': [0, 1],
'param5_hi': [4, 5, 6, 7, 8, 9]}
subset_two = {'param1': [0, 1],
'param2_lo': [0, 1, 2, 3, 4, 5],
'param3_lo': [5, 6, 7, 8, 9, 10],
'param4': [0, 1],
'param5_lo': [0, 1, 2, 3, 4, 5]}
# Example of mixed '_hi' and '_lo' intervals
subset_three = {'param1': [0, 1],
'param2_lo': [0, 1, 2, 3, 4, 5],
'param3_hi': [9, 10, 11, 12, 13, 14, 15],
'param4': [0, 1],
'param5_lo': [0, 1, 2, 3, 4, 5]}
...
注意:我想保留键值对。
编辑:添加subset_three以显示混合' _lo'和' _hi'间隔。
答案 0 :(得分:2)
在大多数情况下,您可以使用以下 dict 理解:
subset_1 = {k:v for k,v in intervals.items() if k.endswith('_hi') or not k.endswith('_lo')}
subset_2 = {k:v for k,v in intervals.items() if k.endswith('_lo') or not k.endswith('_hi')}
print(subset_1)
print(subset_2)
输出:
{'param3_hi': [9, 10, 11, 12, 13, 14, 15], 'param1': [0, 1], 'param2_hi': [4, 5, 6, 7, 8, 9], 'param4': [0, 1], 'param5_hi': [4, 5, 6, 7, 8, 9]}
{'param2_lo': [0, 1, 2, 3, 4, 5], 'param1': [0, 1], 'param3_lo': [5, 6, 7, 8, 9, 10], 'param4': [0, 1], 'param5_lo': [0, 1, 2, 3, 4, 5]}
答案 1 :(得分:1)
我认为collections.defaultdict
和itertools.product
在这里都很有用。首先,构建一个池,根据它们的开始对键进行排序。然后,构建这些箱的笛卡尔积。
from collections import defaultdict
from itertools import product
pool = defaultdict(list)
for key in intervals:
base = key.split('_')[0]
pool[base].append(key)
subsets = [{key: intervals[key] for key in keys} for keys in product(*pool.values())]
# {'param2_lo': [0, 1, 2, 3, 4, 5], ... , 'param1': [0, 1]}
# {'param5_lo': [0, 1, 2, 3, 4, 5], ..., 'param2_hi': [4, 5, 6, 7, 8, 9]}
# and so on...
答案 2 :(得分:1)
我相信您希望itertools.product
应用于参数中的五个选项集:
choices = [
['param1'],
['param2_lo', 'param2_hi'],
['param3_lo', 'param3_hi'],
['param4'],
['param5_lo', 'param5_hi']
]
for permute in itertools.product(*choices):
....
这足以让你前进吗?
答案 3 :(得分:0)
我认为最好的工具是itertools.product,一个解决方案是:
intervals = {'param1': [0, 1],
'param2_hi': [4, 5, 6, 7, 8, 9],
'param2_lo': [0, 1, 2, 3, 4, 5],
'param3_hi': [9, 10, 11, 12, 13, 14, 15],
'param3_lo': [5, 6, 7, 8, 9, 10],
'param4': [0, 1],
'param5_hi': [4, 5, 6, 7, 8, 9],
'param5_lo': [0, 1, 2, 3, 4, 5]}
import itertools
def get_subsets(intervals):
params_list = set(key.split('_')[0] for key in intervals.keys())
list_keys = [[x for x in intervals.keys() if x.startswith(param)] for param in params_list]
subsets = [{x : intervals[x] for x in sublist} for sublist in itertools.product(*list_keys)]
return subsets
get_subsets(intervals)
# [{'param2_lo': [0, 1, 2, 3, 4, 5], 'param3_hi': [9, 10, 11, 12, 13, 14, 15], 'param5_lo': [0, 1, 2, 3, 4, 5], 'param1': [0, 1], 'param4': [0, 1]}, {'param2_lo': [0, 1, 2, 3, 4, 5], 'param3_hi': [9, 10, 11, 12, 13, 14, 15], 'param1': [0, 1], 'param4': [0, 1], 'param5_hi': [4, 5, 6, 7, 8, 9]}, ...
答案 4 :(得分:0)
您可以使用此示例中的groupby
模块中的product
和itertools
来列出所有可能的组合:
from itertools import groupby, product
intervals = {'param1': [0, 1],
'param2_hi': [4, 5, 6, 7, 8, 9],
'param2_lo': [0, 1, 2, 3, 4, 5],
'param3_hi': [9, 10, 11, 12, 13, 14, 15],
'param3_lo': [5, 6, 7, 8, 9, 10],
'param4': [0, 1],
'param5_hi': [4, 5, 6, 7, 8, 9],
'param5_lo': [0, 1, 2, 3, 4, 5]}
sub = []
for _,v in groupby(sorted(intervals.keys()), lambda x: x[5]):
# Or:
# sub.append(list(v))
sub.append(sorted(list(v)))
for k in product(*sub):
print({j:intervals[j] for j in k})
print("------")
输出:
{'param1': [0, 1], 'param3_hi': [9, 10, 11, 12, 13, 14, 15], 'param2_hi': [4, 5, 6, 7, 8, 9], 'param5_hi': [4, 5, 6, 7, 8, 9], 'param4': [0, 1]}
------
{'param1': [0, 1], 'param3_hi': [9, 10, 11, 12, 13, 14, 15], 'param2_hi': [4, 5, 6, 7, 8, 9], 'param5_lo': [0, 1, 2, 3, 4, 5], 'param4': [0, 1]}
------
{'param1': [0, 1], 'param2_hi': [4, 5, 6, 7, 8, 9], 'param5_hi': [4, 5, 6, 7, 8, 9], 'param3_lo': [5, 6, 7, 8, 9, 10], 'param4': [0, 1]}
------
{'param1': [0, 1], 'param2_hi': [4, 5, 6, 7, 8, 9], 'param3_lo': [5, 6, 7, 8, 9, 10], 'param5_lo': [0, 1, 2, 3, 4, 5], 'param4': [0, 1]}
------
....
------
{'param4': [0, 1], 'param1': [0, 1], 'param5_hi': [4, 5, 6, 7, 8, 9], 'param3_lo': [5, 6, 7, 8, 9, 10], 'param2_lo': [0, 1, 2, 3, 4, 5]}
------
{'param4': [0, 1], 'param1': [0, 1], 'param5_lo': [0, 1, 2, 3, 4, 5], 'param3_lo': [5, 6, 7, 8, 9, 10], 'param2_lo': [0, 1, 2, 3, 4, 5]}
------