计算python字典中某个值的出现次数?

Posted

技术标签:

【中文标题】计算python字典中某个值的出现次数?【英文标题】:count the number of occurrences of a certain value in a dictionary in python? 【发布时间】:2018-06-30 12:14:33 【问题描述】:

如果我有这样的东西:

D = 'a': 97, 'c': 0 , 'b':0,'e': 94, 'r': 97 , 'g':0

如果我想例如将“0”的出现次数计算为一个值而不必迭代整个列表,这是否可能以及如何实现?

【问题讨论】:

sum(1 for value in D.values() if value == 0) @PeterWood 或者更好:sum(value == 0 for value in D.values()) @PeterWood 相反。布尔值整数。 布尔值是一个整数子类。 1==True 即使不是同一个类(数字类型都可以):isinstance(True,int)True 在某种程度上,布尔值是整数,因此它们可以像 @k 一样求和 【参考方案1】:

您可以将其转换为列表,如下所示:

D = 'a': 97, 'c': 0 , 'b':0,'e': 94, 'r': 97 , 'g':0
print(list(D.values()).count(0))
>>3

或迭代值:

print(sum([1 for i in D.values() if i == 0]))
>>3

【讨论】:

【参考方案2】:

或者,使用collections.Counter:

from collections import Counter
D = 'a': 97, 'c': 0 , 'b':0,'e': 94, 'r': 97 , 'g':0

Counter(D.values())[0]
# 3

【讨论】:

【参考方案3】:

正如THIS ANSWER 中提到的,使用operator.countOf() 是可行的方法,但您也可以在sum() 函数中使用生成器,如下所示:

sum(value == 0 for value in D.values())
# Or the following which is more optimized 
sum(1 for v in D.values() if v == 0)

或者作为一种稍微优化和功能性更强的方法,您可以通过将整数的__eq__ 方法作为构造函数传递来使用map 函数。

sum(map((0).__eq__, D.values()))

基准测试:

In [15]: D = dict(zip(range(1000), range(1000)))

In [16]: %timeit sum(map((0).__eq__, D.values()))
49.6 µs ± 770 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [17]: %timeit sum(v==0 for v in D.values())
60.9 µs ± 669 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [18]: %timeit sum(1 for v in D.values() if v == 0)
30.2 µs ± 515 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [19]: %timeit countOf(D.values(), 0)
16.8 µs ± 74.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

请注意,虽然在这种情况下使用map 函数可能会更优化,但为了对这两种方法有更全面和一般的想法,您还应该对相对较大的数据集运行基准测试。然后,您可以根据您拥有的数据结构和数量使用最合适的方法。

【讨论】:

可能会更好,因为生成器往往会慢一些。 事实上,我得到%timeit sum([value == 0 for value in D.values()]) 的速度比生成器表达式版本快。 @juanpa.arrivillaga 当然,但有趣的是(0).__eq__ 不是内置函数,但它在地图上的表现更好。这意味着生成器的缺点(额外的函数调用,__next__ 等)比将非内置函数传递给 map 更具影响力。 另外,实际生成器对象的创建可能比map 对象的创建开销更大,而dict 这么小,会有所作为 sum(1 for value in D.values() if value == 0) 可能更快。但我想说countOf 确实是最好的方法。【参考方案4】:

这是operator.countOf 的工作。

countOf(D.values(), 0)

使用您的示例字典进行基准测试:

1537 ns  1540 ns  1542 ns  Counter(D.values())[0]
 791 ns   800 ns   802 ns  sum(value == 0 for value in D.values())
 694 ns   697 ns   717 ns  sum(map((0).__eq__, D.values()))
 680 ns   682 ns   689 ns  sum(1 for value in D.values() if value == 0)
 599 ns   599 ns   600 ns  sum([1 for i in D.values() if i == 0])
 368 ns   369 ns   375 ns  list(D.values()).count(0)
 229 ns   231 ns   231 ns  countOf(D.values(), 0)

代码(Try it online!):

from timeit import repeat

setup = '''
from collections import Counter
from operator import countOf
D = 'a': 97, 'c': 0 , 'b':0,'e': 94, 'r': 97 , 'g':0
'''

E = [
    'Counter(D.values())[0]',
    'sum(value == 0 for value in D.values())',
    'sum(map((0).__eq__, D.values()))',
    'sum(1 for value in D.values() if value == 0)',
    'sum([1 for i in D.values() if i == 0])',
    'list(D.values()).count(0)',
    'countOf(D.values(), 0)',
]

for _ in range(3):
    for e in E:
        number = 10 ** 5
        ts = sorted(repeat(e, setup, number=number))[:3]
        print(*('%4d ns ' % (t / number * 1e9) for t in ts), e)
    print()

【讨论】:

以上是关于计算python字典中某个值的出现次数?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用字典理解计算文档中每个单词的出现次数

计算Python中出现的次数[重复]

计算选项集合中出现次数的惯用方法

python2 怎么统计列表字符串出现次数

使用 Redshift 计算特定 ID 字段中值的出现次数

python——元组和字典学习笔记