找到Python列表中最常见元素的有效方法是什么?

我的列表项可能不是可哈希的,所以不能使用字典。 同样,在抽取的情况下,应返回索引最低的项。例子:

>>> most_common(['duck', 'duck', 'goose'])
'duck'
>>> most_common(['goose', 'duck', 'duck', 'goose'])
'goose'

当前回答

在这里:

def most_common(l):
    max = 0
    maxitem = None
    for x in set(l):
        count =  l.count(x)
        if count > max:
            max = count
            maxitem = x
    return maxitem

我有一种模糊的感觉,在标准库的某个地方有一个方法可以给你每个元素的计数,但我找不到它。

其他回答

def most_frequent(List):

    counter = 0

    num = List[0]

 

    for i in List:

        curr_frequency = List.count(i)

        if(curr_frequency> counter):

            counter = curr_frequency

            num = i


    return num


List = [2, 1, 2, 2, 1, 3]

print(most_frequent(List))

从这里借鉴,这可以在Python 2.7中使用:

from collections import Counter

def Most_Common(lst):
    data = Counter(lst)
    return data.most_common(1)[0][0]

比Alex的解决方案快4-6倍,比newacct提出的一行程序快50倍。

在CPython 3.6+(任何Python 3.7+)上,上面将选择第一个看到的元素。如果你在旧的Python上运行,为了检索列表中第一个出现的元素,你需要进行两次传递来保持顺序:

# Only needed pre-3.6!
def most_common(lst):
    data = Counter(lst)
    return max(lst, key=data.get)

你想要的在统计中被称为模式,Python当然有一个内置函数来为你做这件事:

>>> from statistics import mode
>>> mode([1, 2, 2, 3, 3, 3, 3, 3, 4, 5, 6, 6, 6])
3

请注意,如果没有“最常见元素”,例如前两个元素并列的情况,这将在Python上引发StatisticsError <=3.7,从3.8开始,它将返回遇到的第一个。

简单的一行代码:

def most_common(lst):
    return max(set(lst), key=lst.count)

如果排序和哈希都不可行,这是一个明显的缓慢的解决方案(O(n²)),但相等比较(==)可用:

def most_common(items):
  if not items:
    raise ValueError
  fitems = [] 
  best_idx = 0
  for item in items:   
    item_missing = True
    i = 0
    for fitem in fitems:  
      if fitem[0] == item:
        fitem[1] += 1
        d = fitem[1] - fitems[best_idx][1]
        if d > 0 or (d == 0 and fitems[best_idx][2] > fitem[2]):
          best_idx = i
        item_missing = False
        break
      i += 1
    if item_missing:
      fitems.append([item, 1, i])
  return items[best_idx]

但是,如果你的列表(n)的长度很大,那么让你的项目可哈希或可排序(正如其他答案所建议的那样)几乎总是能更快地找到最常见的元素。哈希时平均为O(n),排序时最差为O(n*log(n))。