我正在创建供私人使用的工具,但遇到了一个复杂的组合问题。
我有7个类似格式的子字典:
{"D1": {"A": 1, "B": 3, "C":6},
"D2": {"D": 4},
"D3": {"E": 8, "F": 12, "G": 2}.
"D4": {"H": 9, "I": 3}.
"D5": {"J": 2},
"D6": {"K": 8, "L": 1},
"D7": {"M": 2}}
我需要生成所有可能的字典,这些字典将以这种格式组合每个字典中的1个元素:
[{"D1": "A", "D2": "D", "D3": "E", "D4": "H", "D5": "J", "D6": "K", "D7": "M"},
{"D1": "A", "D2": "D", "D3": "F", "D4": "I", "D5": "J", "D6": "L", "D7": "M"},
and all other possible combinations]
输出应为所有DX字典中的元素的所有可能唯一组合的列表。 我可能可以使用一些非常复杂,外观难看的嵌套嵌套有很多if的循环来解决此问题,但是在itertools或类似工具中可能有一种非常不错的方法。
对有效完成该任务有帮助吗? 需要根据大量此类命令来重复执行此任务,因此性能是关键。 谢谢!
答案 0 :(得分:2)
看起来有点复杂,但是很简单:
import itertools
D = [D1, D2, D3, D4, ...]
dicts = [
dict(zip([f'D{i+1}' for i in range(len(D))], iter))
for iter in itertools.product(*[list(d.keys()) for d in D])
]
dict_1 = dicts[0]
dict_2 = dicts[1]
...
dicts = [
{'D1': 'A', 'D2': 'D', 'D3': 'E', 'D4': 'H'},
{'D1': 'A', 'D2': 'D', 'D3': 'E', 'D4': 'I'},
{'D1': 'A', 'D2': 'D', 'D3': 'F', 'D4': 'H'},
{'D1': 'A', 'D2': 'D', 'D3': 'F', 'D4': 'I'},
...
]
生成所有键组合
itertools.product(*[list(d.keys()) for d in D])
使用适当的字典名称组合组合
zip([f'D{i+1}' for i in range(len(D))], iter))
将这两个部分结合起来,然后将每个部分转换成字典
[
dict(zip([f'D{i+1}' for i in range(len(D))], iter))
for iter in itertools.product(*[list(d.keys()) for d in D])
]
答案 1 :(得分:1)
您想要的是字典的笛卡尔积。
幸运的是,itertools
定义了一个product
函数,正是该函数。
dict
用作迭代时,将产生其键,因此product(D1, D2, ...)
将直接产生键的元组,例如('A', 'D', 'F', ...)
。
您需要进行一些调整才能准确获得所需的输出:
from pprint import pprint
import itertools
dicts = [
{"A": 1, "B": 3, "C":6},
{"D": 4},
{"E": 8, "F": 12, "G": 2},
{"H": 9, "I": 3}
]
r = [
{f"D{i}": key for i, key in enumerate(x, 1)}
for x in itertools.product(*dicts)
]
pprint(r)
输出:
[{'D1': 'A', 'D2': 'D', 'D3': 'E', 'D4': 'H'},
{'D1': 'A', 'D2': 'D', 'D3': 'E', 'D4': 'I'},
{'D1': 'A', 'D2': 'D', 'D3': 'F', 'D4': 'H'},
{'D1': 'A', 'D2': 'D', 'D3': 'F', 'D4': 'I'},
{'D1': 'A', 'D2': 'D', 'D3': 'G', 'D4': 'H'},
{'D1': 'A', 'D2': 'D', 'D3': 'G', 'D4': 'I'},
{'D1': 'B', 'D2': 'D', 'D3': 'E', 'D4': 'H'},
{'D1': 'B', 'D2': 'D', 'D3': 'E', 'D4': 'I'},
{'D1': 'B', 'D2': 'D', 'D3': 'F', 'D4': 'H'},
{'D1': 'B', 'D2': 'D', 'D3': 'F', 'D4': 'I'},
{'D1': 'B', 'D2': 'D', 'D3': 'G', 'D4': 'H'},
{'D1': 'B', 'D2': 'D', 'D3': 'G', 'D4': 'I'},
{'D1': 'C', 'D2': 'D', 'D3': 'E', 'D4': 'H'},
{'D1': 'C', 'D2': 'D', 'D3': 'E', 'D4': 'I'},
{'D1': 'C', 'D2': 'D', 'D3': 'F', 'D4': 'H'},
{'D1': 'C', 'D2': 'D', 'D3': 'F', 'D4': 'I'},
{'D1': 'C', 'D2': 'D', 'D3': 'G', 'D4': 'H'},
{'D1': 'C', 'D2': 'D', 'D3': 'G', 'D4': 'I'}]
答案 2 :(得分:1)
itertools product
是你的朋友:
from itertools import product
d = {"D1": {"A": 1, "B": 3, "C":6},
"D2": {"D": 4},
"D3": {"E": 8, "F": 12, "G": 2},
"D4": {"H": 9, "I": 3},
"D5": {"J": 2},
"D6": {"K": 8, "L": 1},
"D7": {"M": 2}}
res = []
for c in product(*(v.keys() for _, v in d.items())):
res.append(dict(zip(d.keys(), c)))
列表综合版本为:
res = [dict(zip(d.keys(), c)) for c in product(*(v.keys() for _, v in d.items()))]
产生:
[{'D1': 'A', 'D2': 'D', 'D3': 'E', 'D4': 'H', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'A', 'D2': 'D', 'D3': 'E', 'D4': 'H', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'A', 'D2': 'D', 'D3': 'E', 'D4': 'I', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'A', 'D2': 'D', 'D3': 'E', 'D4': 'I', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'A', 'D2': 'D', 'D3': 'F', 'D4': 'H', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'A', 'D2': 'D', 'D3': 'F', 'D4': 'H', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'A', 'D2': 'D', 'D3': 'F', 'D4': 'I', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'A', 'D2': 'D', 'D3': 'F', 'D4': 'I', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'A', 'D2': 'D', 'D3': 'G', 'D4': 'H', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'A', 'D2': 'D', 'D3': 'G', 'D4': 'H', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'A', 'D2': 'D', 'D3': 'G', 'D4': 'I', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'A', 'D2': 'D', 'D3': 'G', 'D4': 'I', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'B', 'D2': 'D', 'D3': 'E', 'D4': 'H', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'B', 'D2': 'D', 'D3': 'E', 'D4': 'H', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'B', 'D2': 'D', 'D3': 'E', 'D4': 'I', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'B', 'D2': 'D', 'D3': 'E', 'D4': 'I', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'B', 'D2': 'D', 'D3': 'F', 'D4': 'H', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'B', 'D2': 'D', 'D3': 'F', 'D4': 'H', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'B', 'D2': 'D', 'D3': 'F', 'D4': 'I', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'B', 'D2': 'D', 'D3': 'F', 'D4': 'I', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'B', 'D2': 'D', 'D3': 'G', 'D4': 'H', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'B', 'D2': 'D', 'D3': 'G', 'D4': 'H', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'B', 'D2': 'D', 'D3': 'G', 'D4': 'I', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'B', 'D2': 'D', 'D3': 'G', 'D4': 'I', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'C', 'D2': 'D', 'D3': 'E', 'D4': 'H', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'C', 'D2': 'D', 'D3': 'E', 'D4': 'H', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'C', 'D2': 'D', 'D3': 'E', 'D4': 'I', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'C', 'D2': 'D', 'D3': 'E', 'D4': 'I', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'C', 'D2': 'D', 'D3': 'F', 'D4': 'H', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'C', 'D2': 'D', 'D3': 'F', 'D4': 'H', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'C', 'D2': 'D', 'D3': 'F', 'D4': 'I', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'C', 'D2': 'D', 'D3': 'F', 'D4': 'I', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'C', 'D2': 'D', 'D3': 'G', 'D4': 'H', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'C', 'D2': 'D', 'D3': 'G', 'D4': 'H', 'D5': 'J', 'D6': 'L', 'D7': 'M'},
{'D1': 'C', 'D2': 'D', 'D3': 'G', 'D4': 'I', 'D5': 'J', 'D6': 'K', 'D7': 'M'},
{'D1': 'C', 'D2': 'D', 'D3': 'G', 'D4': 'I', 'D5': 'J', 'D6': 'L', 'D7': 'M'}]
优缺点
(+)与其他答案不同,该答案不依赖于遵循D<i>
模式的子对象的命名;他们可以叫什么。
(-)必须保留字典的顺序,因此您需要Python 3.5 +