2017-06-11 30 views
0

我有一個大字典獲取所有可能的對:600個鍵與項目=大名單(約10000-20000元)。從多個大型列表

我的目標是從字典每個列表獲得對和在一個列表合併。

E.g.我有:

d1 = {'key1': ['a', 'b', 'c', 'd'], 'key2': ['f', 'a']} 

預期結果:

d2 = ['a_b', 'a_c', 'a_d', 'b_c', 'b_d', 'c_d', 'a_f'] 

我的代碼:

d2 = [] 
for k, v in d1.items(): 
    for i, j in itertools.product(v, v): 
     if i>j: 
      a = "_".join(list(set([i, j]))) 
      d2.append(a) 

而且我有一個問題:在終端我的Python腳本說 '打死'。

這可能是由於不適當的內存使用情況。有沒有辦法解決這個問題?

回答

6

你所描述的是不是product,而是combinations

此外如果記憶是一個問題,你最好使用發電機這樣:

from itertools import combinations 

def dic_comb_generator(d1): 
    for v in d1.values(): 
     for t in combinations(sorted(v),2): 
      yield "%s_%s"%t

這裏我們使用sorted(..)先排序元素v使得產生的元組進行排序也是如此。如果你做而不是想組合排序,但按列表的順序發生,你應該刪除sorted(..)函數。此外,我們使用2,因爲我們構造具有兩個元素的組合(元組)。

如果我們兌現輸出,我們得到:

>>> list(dic_comb_generator({'key1': ['a', 'b', 'c', 'd'], 'key2': ['f', 'a']})) 
['a_b', 'a_c', 'a_d', 'b_c', 'b_d', 'c_d', 'a_f'] 

但是如果你使用的發電機在for循環,如:

for elem in dic_comb_generator(d1): 
    print(elem) 

Python將無法構造與所有元素的列表:將生成所有元素,但如果不存儲它們,則用於發射第一個項目的內存可爲,重複使用作爲第二項。尤其是在產品,組合等方面,元素數量可能會非常龐大​​,這可以得到回報:將100M +結果列表存儲在巨大的內存負擔中,而當時處理一個元素具有不斷的內存使用情況。

+0

非常感謝!我怎樣才能將Counter應用於生成器? – uzver

+0

@uzver:簡單'計數器(dic_comb_generator(D1))'。 –

+0

這會導致內存錯誤:( – uzver

3

你可以做這樣的事情:

import itertools as it 
for l in d1.values(): 
    for t in it.combinations(sorted(l), 2): 
     print("_".join(t)) 

顯示:

a_b 
a_c 
a_d 
b_c 
b_d 
c_d 
a_f 

注意:如果您不希望它來進行排序,只需取出sorted函數調用。

+0

如果OP不希望它整理這樣的a,b。? ,C,d只是一個代表性的例子,但如果輸入的是W,G,K,L? –

+0

@Coldspeed在他的示例代碼中有一個'如果我> j'條款使我覺得他想它是但是我會添加一個關於這個的註釋,謝謝你的注意。 – rassar

1

您可以創建一個發電機,不涉及itertools

def dic_comb_generator(d): 
    for val in d.values(): 
     v = sorted(val) 
     for i in range(len(v)): 
      for j in range(i+1, len(v)): 
       yield v[i] + '_' + v[j]