How to get the least common element in a list?
Asked Answered
F

13

46

To find the most common, I know I can use something like this:

most_common = collections.Counter(list).most_common(to_find)

However, I can't seem to find anything comparable, for finding the least common element.

Could I please get recommendations on how to do.

Fabled answered 20/1, 2011 at 2:58 Comment(0)
M
27

Borrowing the source of collections.Counter.most_common and inverting as appropriate:

from operator import itemgetter
import heapq
import collections
def least_common_values(array, to_find=None):
    counter = collections.Counter(array)
    if to_find is None:
        return sorted(counter.items(), key=itemgetter(1), reverse=False)
    return heapq.nsmallest(to_find, counter.items(), key=itemgetter(1))

>>> data = [1,1,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4]
>>> least_common_values(data, 2)
[(1, 2), (2, 4)]
>>> least_common_values([1,1,2,3,3])
[(2, 1), (1, 2), (3, 2)]
>>>
Mayman answered 20/1, 2011 at 3:56 Comment(0)
N
46

most_common without any argument returns all the entries, ordered from most common to least.

So to find the least common, just start looking at it from the other end.

Nitrate answered 20/1, 2011 at 3:2 Comment(0)
H
43

What about

least_common = collections.Counter(array).most_common()[-1]
Heterography answered 20/1, 2011 at 3:4 Comment(0)
M
27

Borrowing the source of collections.Counter.most_common and inverting as appropriate:

from operator import itemgetter
import heapq
import collections
def least_common_values(array, to_find=None):
    counter = collections.Counter(array)
    if to_find is None:
        return sorted(counter.items(), key=itemgetter(1), reverse=False)
    return heapq.nsmallest(to_find, counter.items(), key=itemgetter(1))

>>> data = [1,1,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4]
>>> least_common_values(data, 2)
[(1, 2), (2, 4)]
>>> least_common_values([1,1,2,3,3])
[(2, 1), (1, 2), (3, 2)]
>>>
Mayman answered 20/1, 2011 at 3:56 Comment(0)
K
9

Sorry, late to this thread... Found the docs quite helpful: https://docs.python.org/3.7/library/collections.html

Do a search for 'least', and you'll come across this table which helps on getting more than the last (-1) element in the list:

c.most_common()[:-n-1:-1]       # n least common elements

Here's an example:

n = 50

word_freq = Count(words)
least_common = word_freq.most_common()[:-n-1:-1]
Kaylyn answered 15/5, 2019 at 20:50 Comment(1)
yes, this is a great answer, a implementation of least_common as it wereChose
A
6

To just get the least common element and nothing more:

>>> from collections import Counter
>>> ls = [1, 2, 3, 3, 2, 5, 1, 6, 6]
>>> Counter(ls).most_common()[-1][0]
5
Airhead answered 3/2, 2020 at 14:53 Comment(0)
C
5
def least_common_values(array, to_find):
    """
    >>> least_common_values([1,1,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4], 2)
    [(1, 2), (2, 4)]
    """
    counts = collections.Counter(array)
    return list(reversed(counts.most_common()[-to_find:]))
Clement answered 20/1, 2011 at 3:3 Comment(0)
O
3

I guess you need this:

least_common = collections.Counter(array).most_common()[:-to_find-1:-1]
Outpoint answered 11/3, 2015 at 17:56 Comment(0)
L
3

The easiest way to implement the search of the minimum in an Iterable is as follows:

Counter(your_iterable).most_common()[-1]

That returns a 2-dimensional tuple containing the element at first position and the count of occurrences at second position.

Lioness answered 3/8, 2018 at 19:9 Comment(0)
F
1

You can use a key function:

>>> data=[1,1,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4]
>>> min(data,key=lambda x: data.count(x))
1
>>> max(data,key=lambda x: data.count(x))
4
Fledgy answered 11/7, 2013 at 5:35 Comment(0)
A
1

I would suggest as follows,

least_common = collections.Counter(array).most_common()[len(to_find)-10:len(to_find)]
Abroms answered 13/2, 2016 at 2:45 Comment(0)
A
1

Based on this answer for most common elements: https://stackoverflow.com/a/1518632

Here is a one liner for obtaining the least common element in a list:

def least_common(lst):
    return min(set(lst), key=lst.count)
Accepted answered 30/5, 2017 at 11:30 Comment(1)
This is clever and also allows to calc most common from the similar variant just by converting min() to max()Occupational
D
0

To find n least common elements, use the code:

collections.Counter(iterable)[-n:]

For the least common element, n = 1.

Damicke answered 6/1, 2023 at 8:47 Comment(0)
D
0

It's unlikely that Counter.least_common will be implemented as a built-in method, see this GH issue.

In the meantime, it's possible to create a custom class that inherits from Counter and adds the relevant method:

from collections import Counter


class LeastCounter(Counter):
    def least_common(self, n: int | None = None) -> list[tuple]:
        """List the n least common elements and their counts from the least common
        to the most common. If n is None, then list all element counts.

        >>> Counter('abracadabra').least_common(3)
        [('d', 1), ('c', 1), ('r', 2)]
        """
        least = list(reversed(self.most_common()))
        if n is None:
            return least
        return least[:n]

This can be used to modify an existing Counter object:

existing_counter = Counter("abracadabra")
new_counter = LeastCounter(existing_counter)
print(new_counter.least_common(3))
# [('d', 1), ('c', 1), ('r', 2)]

Or to create a new object that will behave like a Counter but will also have the least_common method:

new_counter = LeastCounter("abracadabra")
print(new_counter.least_common(3))
# [('d', 1), ('c', 1), ('r', 2)]
Dowie answered 21/2 at 3:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.