2013-11-26 58 views
1

我有一本字典,看起來像這樣:獲取元素的組合在字典

a: [a] 
b: [b, c] 
c: [d, e, f] 

鍵的數量和每個列表中元素的個數是預先未知。

我希望能夠在每個列表中獲得所有可能的元素組合。對於上述解釋的輸出會是這樣的:

[a, d, b] 
[a, e, c] 
[a, f, b] 
[a, d, c] 
[a, e, b] 
[a, f, c] 

訂單都在列表中列出,並在列表中列表中的元素(這是一個拗口)沒有關係。

我試過了一個解決方案,我發佈了一個答案,但我很想知道是否有更有效的解決方案。

編輯:只有一個元素可以從字典中的每個鍵獲取。按照上面的示例,您不能有[b d e],因爲d e是從c

回答

3

好吧。我理解這個問題並糾正了我的答案。

請使用list comprehension

>>> d = {"a": [1], "b": [2,3], "c": [4,5,6]} 
>>> values = [v for k,v in d.items()] 
>>> values 
[[1], [4, 5, 6], [2, 3]] 

值的列表,然後使用itertools.product這相當於for循環。

>>> for i in itertools.product(*l): 
...  print i 
... 
(1, 4, 2) 
(1, 4, 3) 
(1, 5, 2) 
(1, 5, 3) 
(1, 6, 2) 
(1, 6, 3) 
+0

會有重疊的實例,否則這將是一個很好的解決方案。如果合併了一個過濾器以確保只有一個元素被從列表中取出,那就行了。爲了清晰起見編輯我的答案。 – wei2912

+0

有一刻。我將編輯答案 – Deck

+0

@ wei2912完成。看看更新 – Deck

0

我想出了這一點:

def _gcd(a, b): 
    while b:  
     a, b = b, a % b 
    return a 

def _lcm(a, b): 
    return a * b // _gcd(a, b) 

def lcm(numbers): 
    return reduce(_lcm, numbers) 

def combinations(dict): 
    lengths = [] 
    for key in dict.keys(): 
     lengths.append(len(dict[key])) 

    lcm_int = lcm(lengths) 
    for key in dict.keys(): 
     values = [] 
     length = len(dict[key]) 
     for i in range(lcm_int): 
      values.append(dict[key][i%length]) 
     dict[key] = values 

    combinations = [] 
    for i in range(lcm_int): 
     values = [] 
     for key in dict.keys(): 
      values.append(dict[key][i]) 
     combinations.append(values) 
    return combinations 

這個代碼是找到字典中的所有列表的長度的LCM。然後,每個列表擴展到這樣的事情:

[a]  -> [a, a, a, a, a, a] 
[b, c] -> [b, c, b, c, b, c] 
[d, e, f] -> [d, e, f, d, e, f] 

之後,它需要每個列表的第一個元素,並將其放置在一個新的列表(組合),並做了同樣的元素的其餘部分。

+0

此方法過於複雜且效率低下,所以我不接受它。 :P – wei2912