Python: Counting maximum occurences of an item in a list with ties allowed

Viewed 804

Right now I am using the classic counting of occurences in a list max(lst,key=lst.count) but if there is a tie in the maximum occurences of two different elements e.g lst = [1,1,2,2], max returns only one element. In our example it will return 1 or 2 . But I need a function which will return both 1 and 2.

4 Answers

Build a Counter from the list and take the items that match the highest count using a list comprehension:

from collections import Counter

lst = [1,1,2,2]

c = Counter(lst)
maximums = [x for x in c if c[x] == c.most_common(1)[0][1]]
print(maximums)
# [1, 2]

The Counter approach take counts in one pass (O(n)) whereas the list.count approach has O(n^2) time complexity as it passes through the list with each call.

This may not be the most elegant solution but it definitely works. First you find the number of the maximum occurrence, then find the elements with that count.

lst = [1,1,2,2,3,4]
max_count = max([lst.count(i) for i in set(lst)])
max_count_values = [i for i in set(lst) if lst.count(i)==max_count]

Good question, as finding the single most common number in a list is trivial with scipy.stats.mode, but there is nothing quite so simple if you want to find all of the different modes.

Calling list.count for each value is needlessly expensive, as this uses O(n^2) time, but computing the counts of each element only requires O(n) time.

Here is a solution using NumPy:

>>> import numpy as np
>>> lst = [1,1,2,2,3]
>>> values, counts = np.unique(lst, return_counts=True)
>>> values[np.argwhere(counts == counts.max())].flatten()
array([1, 2])

A one-liner, but perhaps not the clearest.

set(x for x in lst if lst.count(x)==max(lst.count(x) for x in lst))
Related