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.