在 python 中计算某个值在字典中出现的次数?
count the number of occurrences of a certain value in a dictionary in python?
如果我遇到这样的事情:
D = {'a': 97, 'c': 0 , 'b':0,'e': 94, 'r': 97 , 'g':0}
例如,如果我想计算“0”的出现次数作为一个值,而不必遍历整个列表,这是否可能以及如何实现?
您可以将其转换为列表,如下所示:
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
或者,使用 collections.Counter
:
from collections import Counter
D = {'a': 97, 'c': 0 , 'b':0,'e': 94, 'r': 97 , 'g':0}
Counter(D.values())[0]
# 3
如 using 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
函数可能会更优化,但为了对这两种方法有更全面和通用的想法,您应该 运行 比较大的基准数据集也是如此。然后,您可以根据您拥有的数据结构和数量使用最合适的方法。
这是 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()
如果我遇到这样的事情:
D = {'a': 97, 'c': 0 , 'b':0,'e': 94, 'r': 97 , 'g':0}
例如,如果我想计算“0”的出现次数作为一个值,而不必遍历整个列表,这是否可能以及如何实现?
您可以将其转换为列表,如下所示:
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
或者,使用 collections.Counter
:
from collections import Counter
D = {'a': 97, 'c': 0 , 'b':0,'e': 94, 'r': 97 , 'g':0}
Counter(D.values())[0]
# 3
如 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
函数可能会更优化,但为了对这两种方法有更全面和通用的想法,您应该 运行 比较大的基准数据集也是如此。然后,您可以根据您拥有的数据结构和数量使用最合适的方法。
这是 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()