计算一个字典值在多个键中出现的次数

5
我正在使用Python进行工作。有没有一种方法可以计算字典中的值被多个键找到的次数,然后返回一个计数?如果例如我有50个值并运行一个脚本来完成此操作,我将得到一个类似于以下内容的计数:
1: 23  
2: 15  
3: 7  
4: 5  

上面的内容告诉我有23个值出现在一个键中,15个值出现在两个键中,7个值出现在三个键中,5个值出现在四个键中。
如果我的字典中有多个值对应一个键,那么这个问题会改变吗?
这是我的字典样例(细菌名称):
{'0': ['Pyrobaculum'], '1': ['Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium'], '3': ['Thermoanaerobacter', 'Thermoanaerobacter'], '2': ['Helicobacter', 'Mycobacterium'], '5': ['Thermoanaerobacter', 'Thermoanaerobacter'], '4': ['Helicobacter'], '7': ['Syntrophomonas'], '6': ['Gelria'], '9': ['Campylobacter', 'Campylobacter'], '8': ['Syntrophomonas'], '10': ['Desulfitobacterium', 'Mycobacterium']}
因此,从这个样例中可以看到有8个独特的值,理想的反馈应该是:
1:4
2:3
3:1

这里有4种细菌只在一个键中,3种细菌在两个键中被发现,还有1种细菌在三个键中被发现。


唯一的方法是遍历值。没有花哨的捷径。 - Paul Tomblin
@PaulTomblin,您介意提供一种遍历值的方法吗?它会包括类似for value in dictionary.values():这样的内容吗? - Jen
3个回答

6

除非我理解有误,您想了解以下问题:

  • 对于原始字典中的每个值,不同数量的值出现了多少次?
  • 实质上,您想要的是字典中值的频率

我采取了一种不太优雅的方法,但已为您将问题分解为单个步骤:

d = {'0': ['Pyrobaculum'], '1': ['Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium', 'Mycobacterium'], '3': ['Thermoanaerobacter', 'Thermoanaerobacter'], '2': ['Helicobacter', 'Mycobacterium'], '5': ['Thermoanaerobacter', 'Thermoanaerobacter'], '4': ['Helicobacter'], '7': ['Syntrophomonas'], '6': ['Gelria'], '9': ['Campylobacter', 'Campylobacter'], '8': ['Syntrophomonas'], '10': ['Desulfitobacterium', 'Mycobacterium']}

# Iterate through and find out how many times each key occurs
vals = {}                       # A dictonary to store how often each value occurs.
for i in d.values():
  for j in set(i):              # Convert to a set to remove duplicates
    vals[j] = 1 + vals.get(j,0) # If we've seen this value iterate the count
                                # Otherwise we get the default of 0 and iterate it
print vals

# Iterate through each possible freqency and find how many values have that count.
counts = {}                     # A dictonary to store the final frequencies.
# We will iterate from 0 (which is a valid count) to the maximum count
for i in range(0,max(vals.values())+1):
    # Find all values that have the current frequency, count them
    #and add them to the frequency dictionary
    counts[i] = len([x for x in vals.values() if x == i])

for key in sorted(counts.keys()):
  if counts[key] > 0:
     print key,":",counts[key]

你还可以在 codepad 上测试此代码

太好了!!!这个方法非常有效!谢谢!另外,有没有可能在一个键内不计算重复值(或者我能否在vals = {}步骤之前轻松地删除这些重复项? - Jen

5

如果我理解正确,您想要计算字典值的计数。如果这些值可以使用collections.Counter进行计数,则只需在字典值上调用Counter,然后再次在第一个计数器的值上调用。以下是使用字典的示例,其中键为range(100),值在0到10之间随机:

from collections import Counter
d = dict(enumerate([str(random.randint(0, 10)) for _ in range(100)]))
counter = Counter(d.values())
counts_counter = Counter(counter.values())

编辑:

在问题中添加示例字典后,您需要以稍微不同的方式进行第一次计数(d是问题中的字典):

from collections import Counter
c = Counter()
for v in d.itervalues():
    c.update(set(v))
Counter(c.values())

是的!这就是我想要的,要“计算字典值的计数”!唯一的问题是,我实际上有大约5000个键,而值是单词,更改您发布的内容以反映这一点是否容易?非常感谢您发布答案! - Jen
@Jen,如果你有一个值为字符串的字典,这应该可以工作。但我在另一个答案中看到了你的评论,说你有列表。那就不同了。正如1_CR所说,看到你的字典样本会很有帮助。 - Paulo Almeida
字典本身重要吗?值要么存在,要么不存在。经过几步操作后,这些值都会被转换为整数。实际上,键甚至是不必要的。 - user764357
@LegoStormtroopr,我正在回答你的问题,但是问题已经被编辑过了,现在有点不同了。 - Paulo Almeida

2
你可以使用一个计数器(Counter)Counter
>>>from collections import Counter
>>>d = dict(((1, 1), (2, 1), (3, 1), (4, 2), (5, 2), (6, 3), (7, 3)))
>>>d
{1: 1, 2: 1, 3: 1, 4: 2, 5: 2, 6: 3, 7: 3}
>>>Counter(d.values())
Counter({1: 3, 2: 2, 3: 2})

谢谢您的发布!我尝试了这个,但是因为我的值在列表中,所以出现了错误,这会改变它的工作方式吗? - Jen
@Jen,请在原帖中添加您字典的一个样例部分。 - iruvar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接