【问题标题】:Python: value that occurs the most in a listPython:列表中出现次数最多的值
【发布时间】:2012-12-04 16:32:39
【问题描述】:

我有两个列表如下

x = ['a','a','b','c','b','a']

x = ['a','a','b','c','c','d']

我正在尝试找出每个列表中出现次数最多的值。这是我尝试过的。

def unique_values(output,input):
    for i in input:
        if i not in output:
            output.append(i)
k = []
for i in k:
    unique_values(k,x)
    y.remove(i)

我已经做到了这一点,但我不知道如何在 for i in k: 删除列表中的所有值之前停止它。

【问题讨论】:

标签: python list


【解决方案1】:

如果要查找列表中每个元素的出现次数,可以使用 collections 中的 Counter 模块:-

>>> x = ['a','a','b','c','c','d']

>>> from collections import Counter
>>> count = Counter(x)
>>> count
Counter({'a': 2, 'c': 2, 'b': 1, 'd': 1})
>>> count.most_common()
[('a', 2), ('c', 2), ('b', 1), ('d', 1)]

因此,前两个元素在您的列表中最为常见。

>>> count.most_common()[0]
('a', 2)
>>> count.most_common()[1]
('c', 2)

或者,您也可以将参数传递给most_common() 以指定您想要多少个most-common 元素:-

>>> count.most_common(2)
[('a', 2), ('c', 2)]

更新:-

您也可以先找出max的计数,然后找到具有该值的元素总数,然后可以将其用作most_common()中的参数:-

>>> freq_list = count.values()
>>> freq_list
[2, 2, 1, 1]
>>> max_cnt = max(freq_list)
>>> total = freq_list.count(max_cnt)

>>> most_common = count.most_common(total)
[('a', 2), ('c', 2)]

>>> [elem[0] for elem in most_common]
['a', 'c']

【讨论】:

  • 为什么有人将 Counter 重命名为 cntr?这是非常不合常规的。
  • 没有必要使用 slice 来获取列表中最常见的内容。只需在 most_common(n) 中补充 n
  • @ShawnZhang.. 对。我只是使用它,因为有两个最常见的元素。不过我会添加它。
  • 注意:如果len(x) 很大,那么count.most_common(2)count.most_common()[:2] 更有效
  • 有什么方法可以改变x,但要确保即使只有 1 个或多个最常见的,它仍然会产生所有最常见的?
【解决方案2】:

这是另一个解决方案:

max(zip((x.count(item) for item in set(x)), set(x)))

首先,我们使用 set 得到一个不包含重复元素的集合。

>>> set(x)
{'a', 'c', 'b'}

然后,我们计算每个元素在 x 中的次数。这将返回一个生成器对象,您可以将其设为一个列表以查看其值(通过使用 "[ ... ]" 而不是 "( ... )" ),它将返回 [3, 1, 2]。

>>> (x.count(item) for item in set(x))

然后,我们进行计数并使用 zip 将其与元素配对。首先出现的次数,用于下一步。你可以通过使用 list( ... ) 来查看它的值,它会返回 [(3, 'a'), (1, 'c'), (2, 'b')]。

>>> zip((x.count(item) for item in set(x)), set(x))

最后,我们使用 max 找出哪对出现次数最多。

>>> max(zip((x.count(item) for item in set(x)), set(x)))
(3, 'a')

至于第二个值,解决方案有点长。以上内容在列表理解中使用:

>>> [mitem for mitem in zip((x.count(item) for item in set(x)),set(x)) if mitem[0] == max((x.count(item) for item in set(x)))]
[(2, 'a'), (2, 'c')]

【讨论】:

  • 语句之后,三个括号之后。示例:...)))[-1]
  • 解决方案是O(N**4),即使对于中等大小的列表也是不合理的,例如N=1000,它需要~10**12 操作。您可以轻松地将其改进为O(N**2),与Counter() 相比仍然很差,O(N*log m) 时间复杂度m 是最常见元素的数量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 1970-01-01
  • 1970-01-01
  • 2020-01-26
  • 2021-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多