计算 python 中 2 个字典中冗余值的数量

Count number of redundant values in 2 dictionaries in python

我生成了两个词典:

dict1 = {'Ex1': ['Spata1', 'D', 'E'], 'Ex2': ['Fgg', 'Wfdc2', 'F', 'G']}

dict2={'lnc3': ['Spata1', 'Fgg', 'D'], 'lnc2': ['Fgg', 'E'], 'lnc1': ['Spata1', 'Wfdc2', 'F', 'G']}

我想计算 dict1 的每个键有多少值与 dict2 的每个键的每个值重叠,并在输出文件中报告以下元素:

  1. dict1 的键值
  2. dict1 中键值的长度
  3. dict2 的键值
  4. dict2 中键值的长度
  5. 字典 1 和字典 2 的每个键之间的重叠值数。

例如:

dict1 中的 Ex1 有 3 个键 Spat1、D 和 E。 Ex1 的值与 dict2 的 lnc3(Spata2 和 D)中的 2 个值、lnc2(E)的 1 个值和 lnc1(Spata1)的 1 个值重叠。最终输出应如下所示:

keydict1    length_value_dict1  keydict2    length_value_dict2  Number_of_overlap
Ex1 3   lnc3    3   2
Ex1 3   lnc2    2   1
Ex1 3   lnc1    4   1
Ex2 4   lnc3    3   1
Ex2 4   lnc2    2   1
Ex2 4   lnc1    4   3

这是我的代码:

output = open("Output.txt", "w")
output.write('keydict1\tlength_value_dict1\tkeydict2\tlength_value_dict2\tNumber_of_overlap\n') 
for key, value in dict1.items():
    len1=len(dict1[key]) #gives length of the key
    for vals in value: #to iterate over each of the values corresponding to key
        for key2, value2 in dict2.items(): #iterates over keys and values of second dictionary
            len2=len(dict2[key2])
            counter = 0 #sets counter to 0
            for vals2 in value2:
                if vals == vals2: #checks values if equal to each other
                    counter = counter + 1 #if it is equal, it adds 1 to the counter, then it is supposed to reset it when it gets to next key2
            newline= key,str(len1),key2,str(len2),str(counter) #For some reason, i cant output the file in the command below except if the integers are converted to strings. Not sure if there is a better trick
            output.write('\t'.join(newline)+"\n")

脚本运行没有错误。但是,输出不符合预期。每次循环时,它不会多次添加计数器,然后将每个配对比较写在单独的行上。

我还没弄清楚错误在哪里。以下是上述脚本的输出:

keydict1    length_value_dict1  keydict2    length_value_dict2  Number_of_overlap
Ex2 4   lnc3    3   1
Ex2 4   lnc2    2   1
Ex2 4   lnc1    4   0
Ex2 4   lnc3    3   0
Ex2 4   lnc2    2   0
Ex2 4   lnc1    4   1
Ex2 4   lnc3    3   0
Ex2 4   lnc2    2   0
Ex2 4   lnc1    4   1
Ex2 4   lnc3    3   0
Ex2 4   lnc2    2   0
Ex2 4   lnc1    4   1
Ex1 3   lnc3    3   1
Ex1 3   lnc2    2   0
Ex1 3   lnc1    4   1
Ex1 3   lnc3    3   1
Ex1 3   lnc2    2   0
Ex1 3   lnc1    4   0
Ex1 3   lnc3    3   0
Ex1 3   lnc2    2   1
Ex1 3   lnc1    4   0

你的算法应该是这样的。

for k1, v1 in dict1.items():
    for k2, v2 in dict2.items():
        # now find the number of items that appear in both v1 and v2

但是正如您现在注意到的,您的算法会执行此操作。

for k1, v1 in dict1.items():
    for v in v1:
        for k2, v2 in dict2.items():

实际上,您会发现 v1 中的项目 vv2 中出现了多少次,应该是 0 或 1。因此 for v in v1循环,你多次检查键 k1k2 之间的项目冗余。

现在让我们回到最初的算法。我们只想找到两个列表 v1v2 之间 intersection 中的元素数。由于交集是一个集合概念,我们只需要做 len(set(v1).intersection(v2))。下面是一个无需特殊格式即可实现所有这些的简单代码段。

dict1 = {'Ex1': ['Spata1', 'D', 'E'], 'Ex2': ['Fgg', 'Wfdc2', 'F', 'G']}
dict2 = {'lnc3': ['Spata1', 'Fgg', 'D'], 'lnc2': ['Fgg', 'E'], 'lnc1': ['Spata1', 'Wfdc2', 'F', 'G']}

for k1, v1 in dict1.items():
    for k2, v2 in dict2.items():
        print '%3s %5d %10s %5d %5d' % (k1, len(v1), k2, len(v2), len(set(v1).intersection(v2)))

请注意,字典没有您期望的键排序概念。如果您确实需要,ways 可以解决这个问题。

Ex2     4       lnc3     3     1
Ex2     4       lnc2     2     1
Ex2     4       lnc1     4     3
Ex1     3       lnc3     3     2
Ex1     3       lnc2     2     1
Ex1     3       lnc1     4     1

如果您的列表有重复值,使用集合交集可能会影响您的计数,因为集合会忽略重复元素。找到重叠的传统方法是在 v2 中的每个元素计数上创建一个字典,然后对于 v1 中的每个项目,查看它在 v2 中存在的次数以及总结一下总数。在代码中:

from collections import Counter

v2_counts = Counter(v2)
overlap = sum(v2_counts.get(v, 0) for v in v1)

方法 get(key, default_value) 尝试使用键 key 获取字典的值,如果不存在,它将 return default_value.