4

I have a list such as this:

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

I would like to find all the elements which occur most frequently. So I would like:

most = [1, 3, 5]

1, 3, and 5 would occur the most, which is 4 times. What's a fast, pythonic way to do this? I tried methods shown here:

How to find most common elements of a list?.

But it only gives me the top 3, I need all elements. Thank you.

Community
  • 1
  • 1
  • 1
    That answer in the link does a slice `popular_words[:3]` to only return the top 3. The actual counter contains all totals, not just the top 3. – krock Feb 19 '17 at 02:17

3 Answers3

10

With collections.Counter and a list comprehension:

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]

You can generalize for values with highest count by using max on the counter values:

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

For large iterables, to efficiently iterate through the counter and stop once the required items have been taken, you can use itertools.takewhile with most_common without any parameters:

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]

You gain by not having to iterate through all the items in the counter object, although there is some overhead with having to sort the items using most_common; so I'm sure if this absolutely efficient after all. You could do some experiments with timeit.

Moses Koledoye
  • 71,737
  • 8
  • 101
  • 114
1

You can also get the same result with groupby from itertools module and list comprehension in this way:

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]

Output:

print(final)
>>> [1, 3, 5]
Chiheb Nexus
  • 7,803
  • 4
  • 25
  • 38
0

You can do the following if you like to print all the most frequent,

    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]

Please note, if you want to limit, you can enter the number inside most_common() function. Ex: ...most_common(3)]. Hope this answers your question.

i.n.n.m
  • 2,311
  • 6
  • 21
  • 43