私はこれがそれを行うべきだと思います:
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)) 操作であるためです。これは安価ですが、必要な回数の 2 倍の回数を実行すると合計できます。