2017-06-11 29 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]