簡體   English   中英

來自不同大小集合的元素的所有可能組合

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM