[英]How to generate all the possible combinations for a list of elements grouped in different sizes?
[英]All possible combinations of elements from sets of different sizes
我正在創建供私人使用的工具,但遇到了一個復雜的組合問題。
我有類似格式的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或類似工具中可能有一種非常不錯的方法。
對有效執行該任務有任何幫助嗎? 需要根據大量此類命令來重復執行此任務,因此性能是關鍵。 謝謝!
看起來有點復雜,但是相當簡單的解決方案:
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])
]
您想要的是字典的笛卡爾積。 幸運的是, 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'}]
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+
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.