找到所有频率最高的元素的Pythonic方式?

4

我有一个类似于这样的列表:

lst = [1, 3, 5, 1, 5, 6, 1, 1, 3, 4, 5, 2, 3, 4, 5, 3, 4]

我希望找到出现最频繁的所有元素。因此,我希望:

most = [1, 3, 5]

1、3和5出现的次数最多,总共出现了4次。有没有一种快速且pythonic的方法来做到这一点呢?我尝试过这里所示的方法,但仅提供前三个结果,我需要所有元素。谢谢。


1
该链接中的答案使用切片popular_words[:3]仅返回前三个。实际计数器包含所有总数,而不仅仅是前三个。 - krock
3个回答

10

使用 collections.Counter 和列表推导式:

from collections import Counter

lst = [1, 3, 5, 1, 5, 6, 1, 1, 3, 4, 5, 2, 3, 4, 5, 3, 4]
r = [x for x, _ in Counter(lst).most_common(3)]
print(r)
# [1, 3, 5]

您可以使用计数器的值上使用max函数来概括具有最高计数的值:

c = Counter(lst)
m = max(c.values())
r = [k for k in c if c[k] == m]
print(r)
# [1, 3, 5]

对于大型的可迭代对象,要高效地迭代计数器并在获取所需项后停止,可以使用没有任何参数的 most_commonitertools.takewhile

from itertools import takewhile

c = Counter(lst)
m = max(c.values())
r = [x for x, _ in takewhile(lambda x: x[1]==m, c.most_common())] 
print(r)
# [1, 3, 5]

使用most_common对项进行排序存在一些开销,但是不必迭代计数器对象中的所有项,因此您可以从中受益,虽然我确信这样做并非绝对高效。您可以使用timeit进行一些实验。


这个代码是可以运行的,但我想找到所有出现频率最高的元素,而不仅仅是前三个。谢谢你的帮助。 - Arjun Vasudevan
@ArjunVasudevan 我已经更新了一个通用情况的内容 - Moses Koledoye

1

您也可以通过从 itertools 模块使用 groupbylist comprehension 来以同样的方式获得相同的结果:

from itertools import groupby

a = [1, 3, 5, 1, 5, 6, 1, 1, 3, 4, 5, 2, 3, 4, 5, 3, 4]
most_common = 3
final = [k for k,v in groupby(sorted(a), lambda x: x) if len(list(v)) > most_common]

输出:

print(final)
>>> [1, 3, 5]

1
好的,这假设您已经有一个先验阈值。 - Moses Koledoye
是的,这是真的。然而,它可以扩展以处理所有情况。 - Chiheb Nexus

0
如果您想打印所有最常见的内容,可以执行以下操作:
    from collections import Counter
    words=[1, 3, 5, 1, 5, 6, 1, 1, 3, 4, 5, 2, 3, 4, 5, 3, 4]
    most= [word for word, word_count in Counter(words).most_common()]
    print (most)
>>> 
[1, 3, 5, 4, 2, 6]

请注意,如果您想限制数量,可以在most_common()函数内输入数字。例如:...most_common(3)]。希望这回答了您的问题。

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