如果我们查看Counter 的源代码,我们会看到它使用heapq 保留O(n + k log n),其中k 是想要的密钥数量,n 是Counter 的大小,而不是O(n log n)。
def most_common(self, n=None):
'''List the n most common elements and their counts from the most
common to the least. If n is None, then list all element counts.
>>> Counter('abcdeabcdabcaba').most_common(3)
[('a', 5), ('b', 4), ('c', 3)]
'''
# Emulate Bag.sortedByCount from Smalltalk
if n is None:
return sorted(self.items(), key=_itemgetter(1), reverse=True)
return _heapq.nlargest(n, self.items(), key=_itemgetter(1))
因为这不仅仅是O(n),我们可以只过滤计数器并获取它的项目:
counts = Counter([(1, "A"), (2, "A"), (1, "A"), (2, "B"), (1, "B")])
Counter({(f1, f2): n for (f1, f2), n in counts.items() if f2 == "A"}).most_common(2)
#>>> [((1, 'A'), 2), ((2, 'A'), 1)]
虽然展开它可能会稍微快一点,但如果这很重要的话:
import heapq
from operator import itemgetter
filtered = [((f1, f2), n) for (f1, f2), n in counts.items() if f2 == "A"]
heapq.nlargest(2, filtered, key=itemgetter(1))
#>>> [((1, 'A'), 2), ((2, 'A'), 1)]