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

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

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

当前回答

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))

其他回答

这是一个很简单的解,时间复杂度是线性的

L =['鹅','鸭','鸭']

def most_common (L):

current_winner = 0
max_repeated = None
for i in L:
    amount_times = L.count(i)
    if amount_times > current_winner:
        current_winner = amount_times
        max_repeated = i

return max_repeated

打印(most_common (L)

“鸭子”

number是列表中重复次数最多的元素吗

>>> li  = ['goose', 'duck', 'duck']

>>> def foo(li):
         st = set(li)
         mx = -1
         for each in st:
             temp = li.count(each):
             if mx < temp:
                 mx = temp 
                 h = each 
         return h

>>> foo(li)
'duck'

你想要的在统计中被称为模式,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开始,它将返回遇到的第一个。

提出了这么多解决方案,我很惊讶没有人提出我认为明显的解决方案(对于不可哈希但可比较的元素)——[itertools.groupby][1]。Itertools提供了快速、可重用的功能,并允许您将一些棘手的逻辑委托给经过良好测试的标准库组件。举个例子:

import itertools
import operator

def most_common(L):
  # get an iterable of (item, iterable) pairs
  SL = sorted((x, i) for i, x in enumerate(L))
  # print 'SL:', SL
  groups = itertools.groupby(SL, key=operator.itemgetter(0))
  # auxiliary function to get "quality" for an item
  def _auxfun(g):
    item, iterable = g
    count = 0
    min_index = len(L)
    for _, where in iterable:
      count += 1
      min_index = min(min_index, where)
    # print 'item %r, count %r, minind %r' % (item, count, min_index)
    return count, -min_index
  # pick the highest-count/earliest item
  return max(groups, key=_auxfun)[0]

当然,这可以写得更简洁,但我的目标是尽可能清晰。这两个print语句可以取消注释,以便更好地查看运行中的机制;例如,不加注释的打印:

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

发出:

SL: [('duck', 1), ('duck', 2), ('goose', 0), ('goose', 3)]
item 'duck', count 2, minind 1
item 'goose', count 2, minind 0
goose

如您所见,SL是一个对的列表,每对都是一个项目,后面是该项目在原始列表中的索引(为了实现关键条件,如果具有相同最高计数的“最常见”项目是> 1,则结果必须是最早出现的项目)。

Groupby只根据项目分组(通过operator.itemgetter)。辅助函数在max计算期间每分组调用一次,接收并在内部解包一个组——一个包含两个项目(item, iterable)的元组,其中iterable的项目也是两个项目元组,(item,原始索引)[[SL的项目]]。

然后辅助函数使用循环来确定组的可迭代对象中条目的计数和最小原始索引;它将返回这些组合的“质量键”,并更改了最小索引符号,以便Max操作将考虑原始列表中较早出现的那些项。

如果在时间和空间上少考虑一些大o问题,这段代码就会简单得多,例如....:

def most_common(L):
  groups = itertools.groupby(sorted(L))
  def _auxfun((item, iterable)):
    return len(list(iterable)), -L.index(item)
  return max(groups, key=_auxfun)[0]

同样的基本思想,只是表达得更简单简洁……但是,唉,额外的O(N)辅助空间(将组的可迭代对象包含到列表中)和O(N平方)时间(获得每个项目的L.index)。虽然过早的优化是编程中的万恶之源,但当O(N log N)方法可用时,却故意选择O(N²)方法,这太违背可伸缩性了!-)

最后,对于那些更喜欢“单行程序”而不是清晰和性能的人来说,一个额外的单行程序版本,它的名字被适当地扭曲了:-)。

from itertools import groupby as g
def most_common_oneliner(L):
  return max(g(sorted(L)), key=lambda(x, v):(len(list(v)),-L.index(x)))[0]
 def most_common(lst):
    if max([lst.count(i)for i in lst]) == 1:
        return False
    else:
        return max(set(lst), key=lst.count)