在python中,如何按元素的频率对列表进行排序

Posted

技术标签:

【中文标题】在python中,如何按元素的频率对列表进行排序【英文标题】:In python, how to sort list by frequency of elements 【发布时间】:2014-10-10 09:07:24 【问题描述】:

我有一个元素列表:[ 3, 3, 6, 6, 6, 5, 5, 8 ],需要按元素的频率对其进行排序以获得此:[ 6, 6, 6, 3, 3, 5, 5, 8 ] 的几个元素具有相同的频率,按值对它们进行排序。你能找到比这更短的方法吗?

import collections
from operator import itemgetter, attrgetter

def freq_sort(arr):
    counter=collections.Counter(arr)
    com = sorted(counter.most_common(), key=itemgetter(1,0), reverse=True)
    com = map(lambda x: [x[0]] * x[1], com)
    return [item for sublist in com for item in sublist]

【问题讨论】:

属于 codereview.stackexchance。 定义“更短”。 Darth Kotik 提出的答案在字符方面更短,但它不必要地为列表中的每个唯一元素执行一个额外的循环。附带说明一下,如果在具有可变元素的列表中使用给定的解决方案,则会产生问题。 【参考方案1】:

试试这个

>>> old_list = [ 3, 3, 6, 6, 6, 5, 5, 8 ]
new_list = sorted(old_list, key = old_list.count, reverse=True)
>>> new_list
[6, 6, 6, 3, 3, 5, 5, 8]

【讨论】:

当计数相等时,这不会按值排序。也有 list.count 作为关键功能不是很有效(使排序 O(N*N)) 您能否进行一些基准测试以显示执行时间与相关解决方案的比较? 如果old_list 的长度足够,你会想记住old_list.count【参考方案2】:

collections.Counter 方法 most_common() 几乎可以满足您的需求。它返回按频率排序的对(值,频率)。您还需要按值对列表进行排序;该方法不能保证它(规范说当频率相同时,值的顺序是任意的)。所以我们必须将它传递给 sorted() 函数。

代码如下:

from collections import Counter

l = [ 3, 3, 6, 6, 6, 5, 5, 8 ]
c = Counter(l)
sc = sorted(c.most_common(), key=lambda x: (-x[1], x[0])) # sorting happens here
sl = [([v] * n) for (v, n) in sc]
ss = sum(sl, [])
print(ss)

与其他方法相比,该方法的优势在于它只在时间上运行 O(m log m),其中 m 是 l 中的多个不同值。其他方法将在时间 O(n log n) 中运行,其中 n 是长度 o l,它总是大于或等于不同值的数量。您基本上将使用桶排序算法。

【讨论】:

【参考方案3】:

这在行数方面有点短,首先按计数排序,然后按值排序:

import collections
arr = [ 3, 3, 6, 6, 6, 5, 5, 8 ]
counter = collections.Counter(arr)
sorted( arr, key=lambda x: (counter[x], x), reverse=True )

【讨论】:

应该是(counter[x], -x)才能得到正确的顺序【参考方案4】:

执行两种排序通常比 lambda 函数的额外开销要快。这是因为 Python 的排序是稳定的

>>> from collections import Counter
>>> L = [ 3, 3, 6, 6, 6, 5, 5, 8 ]
>>> c = Counter(L)
>>> sorted(sorted(L), key=c.get, reverse=True)
[6, 6, 6, 3, 3, 5, 5, 8]

第二次排序非常快,因为数据现在已经部分排序,这是 timsort 擅长的。

【讨论】:

以上是关于在python中,如何按元素的频率对列表进行排序的主要内容,如果未能解决你的问题,请参考以下文章

计算列表中单词的频率并按频率排序

Python - 如何按每个列表中的第四个元素对列表列表进行排序? [复制]

我想要一些关于如何根据元素频率对列表进行排序的帮助[重复]

Pythonic 按字段名称对命名元组列表进行排序的方法

按频率排序列表

python 使用 sorted 对 列表嵌套元组的数据进行排序