python - 列表嵌套字典的笛卡尔积
问题描述
我有一些代码可以生成列表字典的所有组合
import itertools
import collections
def gen_combinations(d):
keys, values = d.keys(), d.values()
combinations = itertools.product(*values)
for c in combinations:
yield dict(zip(keys, c))
假设我有一本A
字典
A = {'a': [0, 1],
'b': [2, 3, 4]}
它产生:
{'a': 0, 'b': 2}
{'a': 0, 'b': 3}
{'a': 0, 'b': 4}
{'a': 1, 'b': 2}
{'a': 1, 'b': 3}
{'a': 1, 'b': 4}
现在我希望它与嵌套的列表字典一起使用
B = {'s1': {'a': [0, 1],
'b': [0, 1, 2] },
's2': {'c': [0, 1],
'd': [0, 1] }}
这应该产生类似的东西:
{'s1': {'a': 0, 'b': 0},
's2': {'c': 0, 'd': 0}}
{'s1': {'a': 0, 'b': 0},
's2': {'c': 0, 'd': 1}}
{'s1': {'a': 0, 'b': 0},
's2': {'c': 1, 'd': 0}}
{'s1': {'a': 0, 'b': 0},
's2': {'c': 1, 'd': 1}}
等等所有组合......我正在寻找一种优雅的方式来做到这一点。没有任何特定的性能限制,它们是小型字典。
解决方案
最终得到了任意嵌套字典的递归版本:
import itertools
def gen_combinations(d):
keys, values = d.keys(), d.values()
values_choices = (gen_combinations(v) if isinstance(v, dict) else v for v in values)
for comb in itertools.product(*values_choices):
yield dict(zip(keys, comb))
B = {'s1': {'a': [0, 1],
'b': [0, 1, 2] },
's2': {'c': [0, 1],
'd': [0, 1] }}
for c in gen_combinations(B):
print(c)
输出:
{'s1': {'a': 0, 'b': 0}, 's2': {'c': 0, 'd': 0}}
{'s1': {'a': 0, 'b': 0}, 's2': {'c': 0, 'd': 1}}
{'s1': {'a': 0, 'b': 0}, 's2': {'c': 1, 'd': 0}}
{'s1': {'a': 0, 'b': 0}, 's2': {'c': 1, 'd': 1}}
{'s1': {'a': 0, 'b': 1}, 's2': {'c': 0, 'd': 0}}
{'s1': {'a': 0, 'b': 1}, 's2': {'c': 0, 'd': 1}}
{'s1': {'a': 0, 'b': 1}, 's2': {'c': 1, 'd': 0}}
{'s1': {'a': 0, 'b': 1}, 's2': {'c': 1, 'd': 1}}
{'s1': {'a': 0, 'b': 2}, 's2': {'c': 0, 'd': 0}}
{'s1': {'a': 0, 'b': 2}, 's2': {'c': 0, 'd': 1}}
{'s1': {'a': 0, 'b': 2}, 's2': {'c': 1, 'd': 0}}
{'s1': {'a': 0, 'b': 2}, 's2': {'c': 1, 'd': 1}}
{'s1': {'a': 1, 'b': 0}, 's2': {'c': 0, 'd': 0}}
{'s1': {'a': 1, 'b': 0}, 's2': {'c': 0, 'd': 1}}
{'s1': {'a': 1, 'b': 0}, 's2': {'c': 1, 'd': 0}}
{'s1': {'a': 1, 'b': 0}, 's2': {'c': 1, 'd': 1}}
{'s1': {'a': 1, 'b': 1}, 's2': {'c': 0, 'd': 0}}
{'s1': {'a': 1, 'b': 1}, 's2': {'c': 0, 'd': 1}}
{'s1': {'a': 1, 'b': 1}, 's2': {'c': 1, 'd': 0}}
{'s1': {'a': 1, 'b': 1}, 's2': {'c': 1, 'd': 1}}
{'s1': {'a': 1, 'b': 2}, 's2': {'c': 0, 'd': 0}}
{'s1': {'a': 1, 'b': 2}, 's2': {'c': 0, 'd': 1}}
{'s1': {'a': 1, 'b': 2}, 's2': {'c': 1, 'd': 0}}
{'s1': {'a': 1, 'b': 2}, 's2': {'c': 1, 'd': 1}}
推荐阅读
- javascript - Firebase:获取数据在 React Native 中不起作用
- javascript - 如何确保我的函数一次只作用于一个元素?(转发更多细节)
- javascript - JavaScript:递归函数无法正确处理 Promise
- c - pow() 有时有时在 gcc 中找不到 w/o -lm 开关
- r - SAS proc 表示 R 中的等价物
- java - 通过保留现有规则向单例 KieContainer 添加新规则
- jquery - jQuery在滚动之前获取滚动位置以在全屏时使用scrollTop()位置临时禁用滚动
- django - 在 Django 中,如何重命名用户模型?
- r - 计算每行超过 60 的值的数量
- firebase - FIRESTORE :具有多个 where 子句的查询流