2015-04-01 75 views
0

你好Stackoverlow成員鍵的變體數量,級聯字典的Python(遞歸?)

我想,另一方面串聯鍵(串)在手,和值(列表),的一個詞典。

爲了您更好的瞭解,下面是我在開頭:

dict = {'bk1': 
      {'k11': ['a1', 'b1', 'c1'], 
      'k12': ['a2', 'b2', 'c2']}, 
     'bk2': 
      {'k21': ['d1', 'e1'], 
      'k22': ['d2', 'e2'], 
      'k23': ['d3', 'e3']}, 
     'bk3': 
      {'k31': ['f1', 'g1', 'h1'], 
      'k32': ['f2', 'g2', 'h2']} 
     } 

這裏是我想什麼底:

newdict = {'k11_k21_k31': ['a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h1'], 
      'k11_k21_k32': ['a1', 'b1', 'c1', 'd1', 'e1', 'f2', 'g2', 'h2'], 
      'k11_k22_k31': ['a1', 'b1', 'c1', 'd2', 'e2', 'f1', 'g1', 'h1'], 
      'k11_k22_k32': ['a1', 'b1', 'c1', 'd2', 'e2', 'f2', 'g2', 'h2'], 
      'k11_k23_k31': ['a1', 'b1', 'c1', 'd3', 'e3', 'f1', 'g1', 'h1'], 
      'k11_k23_k32': ['a1', 'b1', 'c1', 'd3', 'e3', 'f2', 'g2', 'h2'], 
      'k12_k21_k31': ['a2', 'b2', 'c2', 'd1', 'e1', 'f1', 'g1', 'h1'], 
      'k12_k21_k32': ['a2', 'b2', 'c2', 'd1', 'e1', 'f2', 'g2', 'h2'], 
      'k12_k22_k31': ['a2', 'b2', 'c2', 'd2', 'e2', 'f1', 'g1', 'h1'], 
      'k12_k22_k32': ['a2', 'b2', 'c2', 'd2', 'e2', 'f2', 'g2', 'h2'], 
      'k12_k23_k31': ['a2', 'b2', 'c2', 'd3', 'e3', 'f1', 'g1', 'h1'], 
      'k12_k23_k32': ['a2', 'b2', 'c2', 'd3', 'e3', 'f2', 'g2', 'h2']} 

我想這樣做與:

  • 「大鍵」(BKI),以及一個變種號每個bki,一個變體密鑰數目(kij)。

  • 「大鍵」之間的「完全組合」。舉例來說,我不希望類似的結果:

    {'k11_k23': ['a1', 'b1', 'c1', 'd3', 'e3']} 
    

其中 「BK3」 被遺漏。

我有鱗片狀嘗試「for」循環,但循環的次數取決於「大鑰匙」的數量...

然後,我覺得這個問題可以用遞歸來解決(也許?) ,但儘管我的研究和實施它的意願,我失敗了。

任何幫助「遞歸與否」的解決方案將不勝感激。

謝謝


Whoaa,有什麼反應! 非常感謝您的快速回答,它的作品完美!

+0

將Python的[itertools.product( )](https://docs.python.org/2/library/itertools.html)的幫助? – jksnw 2015-04-01 13:45:51

回答

3

正如意見建議的@jksnw,您可以使用itertools.product做到這一點:

import itertools 

dct = { 
    'bk1': { 
     'k11': ['a1', 'b1', 'c1'], 
     'k12': ['a2', 'b2', 'c2'] 
    }, 
    'bk2':{ 
     'k21': ['d1', 'e1'], 
     'k22': ['d2', 'e2'], 
     'k23': ['d3', 'e3'] 
    }, 
    'bk3': { 
     'k31': ['f1', 'g1', 'h1'], 
     'k32': ['f2', 'g2', 'h2'] 
    } 
} 

big_keys = dct.keys() 
small_keys = (dct[big_key].keys() for big_key in big_keys) 

res = {} 
for keys_from_each in itertools.product(*small_keys): 
    key = "_".join(keys_from_each) 

    value = [] 
    for big_key, small_key in zip(big_keys, keys_from_each): 
     value.extend(dct[big_key][small_key]) 

    res[key] = value 

這樣:

>>> res 

{'k11_k21_k31': ['a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h1'], 
'k11_k21_k32': ['a1', 'b1', 'c1', 'd1', 'e1', 'f2', 'g2', 'h2'], 
'k11_k22_k31': ['a1', 'b1', 'c1', 'd2', 'e2', 'f1', 'g1', 'h1'], 
'k11_k22_k32': ['a1', 'b1', 'c1', 'd2', 'e2', 'f2', 'g2', 'h2'], 
'k11_k23_k31': ['a1', 'b1', 'c1', 'd3', 'e3', 'f1', 'g1', 'h1'], 
'k11_k23_k32': ['a1', 'b1', 'c1', 'd3', 'e3', 'f2', 'g2', 'h2'], 
'k12_k21_k31': ['a2', 'b2', 'c2', 'd1', 'e1', 'f1', 'g1', 'h1'], 
'k12_k21_k32': ['a2', 'b2', 'c2', 'd1', 'e1', 'f2', 'g2', 'h2'], 
'k12_k22_k31': ['a2', 'b2', 'c2', 'd2', 'e2', 'f1', 'g1', 'h1'], 
'k12_k22_k32': ['a2', 'b2', 'c2', 'd2', 'e2', 'f2', 'g2', 'h2'], 
'k12_k23_k31': ['a2', 'b2', 'c2', 'd3', 'e3', 'f1', 'g1', 'h1'], 
'k12_k23_k32': ['a2', 'b2', 'c2', 'd3', 'e3', 'f2', 'g2', 'h2']} 

在此,使用itertools.product得到的名單我們從每個塊取得的「小鍵」:

>>> big_keys = dct.keys() 
>>> small_keys = (dct[big_key].keys() for big_key in big_keys) 
>>> list(itertools.product(*small_keys)) 

[('k12', 'k22', 'k31'), 
('k12', 'k22', 'k32'), 
('k12', 'k23', 'k31'), 
('k12', 'k23', 'k32'), 
('k12', 'k21', 'k31'), 
('k12', 'k21', 'k32'), 
('k11', 'k22', 'k31'), 
('k11', 'k22', 'k32'), 
('k11', 'k23', 'k31'), 
('k11', 'k23', 'k32'), 
('k11', 'k21', 'k31'), 
('k11', 'k21', 'k32')] 
2

你可以使用itertools.product,並reduce(lambda x,y:x+y,i)扁平化的嵌套列表,也不要使用dict或其他Python內置類型名稱或關鍵字爲你的變量名字(我用d):

>>> from itertools import product 
>>> v=[i.values() for i in d.values()] 
>>> v=[reduce(lambda x,y:x+y,i) for i in product(*v)] 
>>> k=[i.keys() for i in d.values()] 
>>> k=['_'.join(i) for i in product(*k)] 
>>> {k:v for k,v in zip(k,v)} 
{'k31_k12_k22': ['f1', 'g1', 'h1', 'a2', 'b2', 'c2', 'd2', 'e2'], 
'k32_k12_k21': ['f2', 'g2', 'h2', 'a2', 'b2', 'c2', 'd1', 'e1'],   
'k31_k11_k22': ['f1', 'g1', 'h1', 'a1', 'b1', 'c1', 'd2', 'e2'], 
'k31_k12_k23': ['f1', 'g1', 'h1', 'a2', 'b2', 'c2', 'd3', 'e3'], 
'k32_k12_k22': ['f2', 'g2', 'h2', 'a2', 'b2', 'c2', 'd2', 'e2'], 
'k31_k12_k21': ['f1', 'g1', 'h1', 'a2', 'b2', 'c2', 'd1', 'e1'], 
'k32_k11_k23': ['f2', 'g2', 'h2', 'a1', 'b1', 'c1', 'd3', 'e3'], 
'k32_k12_k23': ['f2', 'g2', 'h2', 'a2', 'b2', 'c2', 'd3', 'e3'], 
'k31_k11_k21': ['f1', 'g1', 'h1', 'a1', 'b1', 'c1', 'd1', 'e1'], 
'k31_k11_k23': ['f1', 'g1', 'h1', 'a1', 'b1', 'c1', 'd3', 'e3'], 
'k32_k11_k21': ['f2', 'g2', 'h2', 'a1', 'b1', 'c1', 'd1', 'e1'], 
'k32_k11_k22': ['f2', 'g2', 'h2', 'a1', 'b1', 'c1', 'd2', 'e2']} 
+0

非常有用的答案,也許它應該包括進口。我知道它是在控制檯上製作的,但我試着通過代碼來了解它的功能,也許它會讓某人感到困惑。 from itertools import product import functools – 2015-04-01 14:25:49

+0

@in python 3'reduce'不是一個內置函數,而是它的'functools'模塊!如果你在3歲,你需要使用它! – Kasramvd 2015-04-01 14:30:26

+0

我在python 2.7。我得到了產品錯誤 – 2015-04-01 14:33:58