在列表中找出出现次数最多的项

79 投票
14 回答
216080 浏览
提问于 2025-04-16 23:09

在Python中,我有一个列表:

L = [1, 2, 45, 55, 5, 4, 4, 4, 4, 4, 4, 5456, 56, 6, 7, 67]  

我想找出在这个列表中出现次数最多的那个项。我已经能解决这个问题了,但我想要最快的方法。我知道有一种很好的Python方式可以做到这一点。

14 个回答

132
from collections import Counter
most_common,num_most_common = Counter(L).most_common(1)[0] # 4, 6 times

对于旧版本的Python(小于2.7),你可以使用这个方法来创建Counter类。

185

我很惊讶没人提到最简单的解决办法,就是用max()配合list.count

max(lst,key=lst.count)

举个例子:

>>> lst = [1, 2, 45, 55, 5, 4, 4, 4, 4, 4, 4, 5456, 56, 6, 7, 67]
>>> max(lst,key=lst.count)
4

这个方法在Python 3和2中都可以用,但要注意,它只会返回出现次数最多的那个项目,而不会告诉你这个项目出现了多少次。而且,如果有多个项目出现次数相同(也就是平局),它只会返回其中一个。

虽然使用max()的时间效率比用Counter.most_common(1)要差,正如PM 2Ring所说,但这个方法得益于快速的C实现。我发现对于短列表,这个方法是最快的,但对于较长的列表就慢了(在IPython 5.3中显示的Python 3.6的时间):

In [1]: from collections import Counter
   ...: 
   ...: def f1(lst):
   ...:     return max(lst, key = lst.count)
   ...: 
   ...: def f2(lst):
   ...:     return Counter(lst).most_common(1)
   ...: 
   ...: lst0 = [1,2,3,4,3]
   ...: lst1 = lst0[:] * 100
   ...: 

In [2]: %timeit -n 10 f1(lst0)
10 loops, best of 3: 3.32 us per loop

In [3]: %timeit -n 10 f2(lst0)
10 loops, best of 3: 26 us per loop

In [4]: %timeit -n 10 f1(lst1)
10 loops, best of 3: 4.04 ms per loop

In [5]: %timeit -n 10 f2(lst1)
10 loops, best of 3: 75.6 us per loop
18

这里有一个使用 defaultdict 的解决方案,适用于 Python 2.5 及以上版本:

from collections import defaultdict

L = [1,2,45,55,5,4,4,4,4,4,4,5456,56,6,7,67]
d = defaultdict(int)
for i in L:
    d[i] += 1
result = max(d.iteritems(), key=lambda x: x[1])
print result
# (4, 6)
# The number 4 occurs 6 times

注意,如果 L = [1, 2, 45, 55, 5, 4, 4, 4, 4, 4, 4, 5456, 7, 7, 7, 7, 7, 56, 6, 7, 67],那么数字 4 和 7 各出现了六次。不过,结果会是 (4, 6),也就是说有六个 4。

撰写回答