我认为应该这样做:
import itertools
import collections
q1 = 'q1'
q2 = 'q2'
q3 = 'q3'
dic_list = {
q1:[1,2,3,4,5],
q2:[2,3,5],
q3:[2,5]
}
#sets are much more efficient for this sort of thing. Create a dict
#of the same structure as the old one, only with `set` as values
#instead of `list`
dic_set = {k:set(v) for k,v in dic_list.items()}
new_dic = collections.defaultdict(dict)
for k1,k2 in itertools.combinations(dic_set,2):
#to get the count, we just need to know the size of the intersection
#of the 2 sets.
value = len(dic_set[k1] & dic_set[k2])
new_dic[k1][k2] = value
new_dic[k2][k1] = value
print (new_dic)
如果您关注评论,事实证明这combinations
比permutations
:
import itertools
import collections
q1 = 'q1'
q2 = 'q2'
q3 = 'q3'
dic_list = {
q1:[1,2,3,4,5],
q2:[2,3,5],
q3:[2,5]
}
dic_set = {k:set(v) for k,v in dic_list.items()}
def combo_solution():
new_dic = collections.defaultdict(dict)
for k1,k2 in itertools.combinations(dic_set,2):
value = len(dic_set[k1] & dic_set[k2])
new_dic[k1][k2] = value
new_dic[k1][k2] = value
return new_dic
def perm_solution():
new_dic = collections.defaultdict(dict)
for k1, k2 in itertools.permutations(dic_set,2):
new_dic[k1][k2] = len(dic_set[k1] & dic_set[k2])
return new_dic
import timeit
print timeit.timeit('combo_solution()','from __main__ import combo_solution',number=100000)
print timeit.timeit('perm_solution()','from __main__ import perm_solution',number=100000)
结果:
0.58366894722 #combinations
0.832300901413 #permutations
这是因为set.intersection
它是一个 O(min(N,M)) 操作——这很便宜,但如果你做的次数是你需要的两倍,则可以加起来。