I need a solution that is O(n) for finding most repeated element in a list. If 2 or more numbers are repeated the same amount of time return smallest number.
from collections import Counter
 
def most_frequent(n):
    count_occurence = Counter(n)
    return count_occurence.most_common(1)[0][0]
input = [2,4,4,5,2,3,3,4,5,6,6,6,1]
Output should be 4 which should give the count of 3
Advertisement
Answer
You could use max and groupby:
from itertools import groupby
def most_frequent(li):
    maxes=[]
    for k,g in groupby(sorted(li)):
        maxes.append((len(list(g)), -k))
        
    return -max(maxes)[1]
Or use a dict as a counter:
def most_frequent(li):
    cnt={}
    for e in li:
        cnt[-e]=cnt.get(-e, 0)+1
    
    return -max(cnt.items(), key=lambda t: (t[1],t[0]))[0]
Or if your data has runs of similar numbers, without the O(n log n) sort step you can combine these two methods:
def most_frequent(li):
    cnt={}
    for k,g in groupby(li):
        cnt[-k]=cnt.get(-k,0)+len(list(g))
        
    return -max(cnt.items(), key=lambda t: (t[1],t[0]))[0]
And it likely is the case that using max on a comprehension is faster than using a lambda:
def most_frequent(li):
    cnt={}
    for k,g in groupby(li):
        cnt[-k]=cnt.get(-k,0)+len(list(g))
                
    return -max(((y,x) for x,y in cnt.items()))[1]
In all cases, you are construction a tuple of (-element_in_list, count_of_that_element):
cnt=[(-2, 2), (-4, 3), (-5, 2), (-3, 2), (-6, 3), (-1, 1)]
You then take that max of that by reversing the tuple either with a comprehension of a key function. Your answer then is -element_in_list since it was negated to take the max.
