如何返回列表中出现次数最多的元素?

7
我正在尝试编写一个函数,它接受一个参数numlist(由数字组成的非空列表),并返回出现频率最高的数字排序列表。
目前我已经创建了一个字典(数字作为键,它们的频率作为值)。但我仍然想找到其中具有最大值的数字并返回它。问题是我不知道如何比较它们。现在有一些类似这样的一行代码:
max(stats, key=stats.get)

但是如果有多个符合要求的值怎么办?
mode([5, 1, 1, 5])
#I'm guessing this should return [1, 5] if sorted...

你会如何处理它?感谢您对此的任何帮助!

这是我的代码:

def mode(numlist):

    mylist = numlist
    dic = {}

    for num in mylist:
        if num in dic:
            dic[num] += 1
        else:
            dic[num] = 1
     # try to get the max value and return them in a set form like [1, 0]    

那么如果你有多个最大值,你想返回一个包含所有最大值的列表?就像6和7都出现相同次数的最大值一样? - idjaw
@idjaw 是的,没错 - 2Xchampion
你能在你的问题中添加一个样例输入和期望输出吗? - Mazdak
@Kasramvd 那里有一个。模式需要 [1, 5] 的输出,我已经检查了要求。对于混淆感到抱歉。 - 2Xchampion
4个回答

5
你可以使用一个 Counter,它返回一个类似字典的对象,其中元素被存储为字典键,它们的计数被存储为字典值。
from collections import Counter

def mode(my_list):
    ct = Counter(my_list)
    max_value = max(ct.values())
    return sorted(key for key, value in ct.items() if value == max_value)

演示:

In [46]: mode([5, 1, 1, 5])
Out[46]: [1, 5]

为什么不在上面的函数示例中直接返回max_value呢? - Zsofia

2

如果您坚持使用当前的实现,可以对字典的值进行排序,然后只需获取与最大值匹配的所有字典键:

因此,在方法结尾处可以执行以下操作:

vals = max(dic.values())
return [k for k, v in dic.items() if v == vals]

变量 vals 将保存最大值,以表示重复项的值。然后我们创建一个列表推导式,通过遍历字典获取所有与该值匹配的键。

将它们组合起来:

def mode(numlist):

    mylist = numlist
    dic = {}

    for num in mylist:
        if num in dic:
            dic[num] += 1
        else:
            dic[num] = 1

    vals = max(dic.values())
    return [k for k, v in dic.items() if v == vals]


print(mode([5, 1, 1, 5]))

输出:

[1, 5]

0
你可以使用 collections.Counter
from collections import Counter

def mode(num_list):
    max_value = float('-inf')
    maxes = None
    for key, value in Counter(num_list).items():
        if value == max_value:
            maxes.add(key)
        elif value > max_value:
            max_value = value
            maxes = {key}

    return maxes


print(mode([1, 3, 3, 1, 2]))

如果顺序很重要,请使用[key]而不是{key},并使用maxes.append(key)而不是maxes.add(key)

0

嗯,你可以使用的一行代码是

def mode(num_list):
    return max(num_list, key = num_list.count)

但是正如你所说,它不能处理具有相同出现次数的多个数字。

我更喜欢继续使用列表而不是字典。下面的函数将返回一个包含所有最高出现次数数字的列表。

def mode(num_list):

    # Make list of tuples with their values and no. occurrences
    # num_list = [5, 1, 1, 5, 5]
    # max_ocur = [(1, 2), (5, 3)]
    max_ocur = [(i, num_list.count(i)) for i in num_list]

    # Set to remove duplicates
    max_ocur = set(max_ocur)

    # Find the max number of occurrences
    m = max(max_ocur, key = lambda x: x[1])[1]

    # Get list of all numbers in max_ocur that have highest occurrence
    modes = [i for i, ocur in max_ocur if ocur == m]

    modes.sort() # Sort if you want

    return modes

或者你可以使用简短版本。我不确定我更喜欢哪一个,我使用上面的那个是因为使用list.count两次感觉效率低下。但我不确定哪一个更高效。

def mode(num_list):

    max_ocur = max([num_list.count(i) for i in num_list])

    return [i for i in set(num_list) if num_list.count(i) == max_ocur]

如果在列表中只有一个数字具有最高出现次数,而您更希望返回该数字本身而不是仅含有一个数字的列表,则可以执行以下操作:
return modes if len(modes) > 1 else modes[0] 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接