给定一个字典,可以获得所有可能的子字典配置

时间:2017-06-26 10:49:55

标签: python-2.7 dictionary combinations enumeration itertools

我遇到以下困难: 鉴于我的输入字典有4个键及其值,例如

global_dict = {'Cloudy': (False, True),
               'Rain': False,
               'Sprinkler': (False, True),
               'WetGrass': (False, True)}

我希望得到所有可能的子词典,每个键只有一个值;优选地在列表中,例如

dict_list = [
    {'WetGrass': False, 'Rain': False, 'Sprinkler': False, 'Cloudy': False},
    {'WetGrass': False, 'Rain': False, 'Sprinkler': False, 'Cloudy': True},
    {'WetGrass': False, 'Rain': False, 'Sprinkler': True, 'Cloudy': False},
    {'WetGrass': False, 'Rain': False, 'Sprinkler': True, 'Cloudy': True},
    {'WetGrass': True, 'Rain': False, 'Sprinkler': False, 'Cloudy': False},
    {'WetGrass': True, 'Rain': False, 'Sprinkler': False, 'Cloudy': True},
    {'WetGrass': True, 'Rain': False, 'Sprinkler': True, 'Cloudy': False},
    {'WetGrass': True, 'Rain': False, 'Sprinkler': True, 'Cloudy': True}
]

我已经尝试了以下内容:

src = {'lblA': (False, True), 'lblB': (False, True), 'lblC': (0, 1, 2)}
labels, terms = zip(*src.items())
print [dict(zip(labels, term)) for term in itertools.product(*terms)]

从这里开始:

Best way to enumerate a cartesian product with labels in python?

但我一直收到错误:

  

TypeError'bool'对象不可迭代

我希望有人可以帮助我。

谢谢!

1 个答案:

答案 0 :(得分:2)

这里的初始问题是你的所有值都是除了'Rain'之外的元组(值为bool并且它不可迭代),所以我也把它变成了元组:

global_dict = {'Cloudy': (False, True),
               'Rain': (False,),
               'Sprinkler': (False, True),
               'WetGrass': (False, True)}

其中(False,)是单元素元组。

最后,我们可以使用itertools.product

创建dict_list
from itertools import product

global_dict = {'Cloudy': (False, True),
               'Rain': (False,),
               'Sprinkler': (False, True),
               'WetGrass': (False, True)}

possible_values = product(*global_dict.values())
dict_list = [dict(zip(global_dict.keys(), values))
             for values in possible_values]

给我们

>>>dict_list
[{'Cloudy': False, 'Rain': False, 'Sprinkler': False, 'WetGrass': False},
 {'Cloudy': False, 'Rain': False, 'Sprinkler': False, 'WetGrass': True},
 {'Cloudy': False, 'Rain': False, 'Sprinkler': True, 'WetGrass': False},
 {'Cloudy': False, 'Rain': False, 'Sprinkler': True, 'WetGrass': True},
 {'Cloudy': True, 'Rain': False, 'Sprinkler': False, 'WetGrass': False},
 {'Cloudy': True, 'Rain': False, 'Sprinkler': False, 'WetGrass': True},
 {'Cloudy': True, 'Rain': False, 'Sprinkler': True, 'WetGrass': False},
 {'Cloudy': True, 'Rain': False, 'Sprinkler': True, 'WetGrass': True}]

测试

desired_dict_list = [
    {'WetGrass': False, 'Rain': False, 'Sprinkler': False, 'Cloudy': False},
    {'WetGrass': False, 'Rain': False, 'Sprinkler': False, 'Cloudy': True},
    {'WetGrass': False, 'Rain': False, 'Sprinkler': True, 'Cloudy': False},
    {'WetGrass': False, 'Rain': False, 'Sprinkler': True, 'Cloudy': True},
    {'WetGrass': True, 'Rain': False, 'Sprinkler': False, 'Cloudy': False},
    {'WetGrass': True, 'Rain': False, 'Sprinkler': False, 'Cloudy': True},
    {'WetGrass': True, 'Rain': False, 'Sprinkler': True, 'Cloudy': False},
    {'WetGrass': True, 'Rain': False, 'Sprinkler': True, 'Cloudy': True}
]

assert (len(dict_list) == len(desired_dict_list) and
        all(dictionary in dict_list
            for dictionary in desired_dict_list))