猿问

按频率对列表进行排序

我想按频率降序对列表进行排序。如果两个值的频率相同,那么我还希望这两个值按降序排列。

例如,

mylist = [1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 5, 5, 5, 4, 4, 4, 4, 4, 4]

我希望我的结果是

[4,4,4,4,4,4,3,3,3,3,3,5,5,5,2,2,2,1,1].

如果我使用

sorted(mylist,key = mylist.count,reverse = True)

我会得到

[4,4,4,4,4,4,3,3,3,3,3,2,2,2,5,5,5,1,1];

我试过

 sorted(mylist,key = lambda x:(mylist.count,-x),reverse = True)

但我认为有些问题,它只给了我结果:

[1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5].

所以我的问题是我怎样才能得到我想要的结果以及为什么结果会是这样

[1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5]

如果我使用

sorted(mylist,key = lambda x:(mylist.count,-x),reverse = True)


慕仙森
浏览 137回答 3
3回答

慕娘9325324

使用 Counter 获取频率,然后按它给出的频率排序:from collections import Counterdef sorted_by_frequency(arr):    counts = Counter(arr)    # secondarily sort by value    arr2 = sorted(arr, reverse=True)    # primarily sort by frequency    return sorted(arr2, key=counts.get, reverse=True)# Usage:>>> sorted_by_frequency([1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 5, 5, 5, 4, 4, 4, 4, 4, 4])[4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 5, 5, 5, 2, 2, 2, 1, 1]

墨色风雨

为什么sorted(mylist,&nbsp;key=lambda&nbsp;x:&nbsp;(mylist.count,&nbsp;-x),&nbsp;reverse=True)出错?它比较键,因此例如两个值3和1成为对(mylist.count, -3)和 ,(mylist.count, -1)并且比较将是(mylist.count, -3) < (mylist.count, -1)。因此,明显的错误是这些对没有预期的数字频率。相反,他们有这个功能。而且功能不亚于它本身。但我发现注意到当时到底发生了什么很有趣。配对比较是如何进行的?您可能认为这(a, b) < (c, d)相当于(a < c) or (a == c and b < d).&nbsp;事实并非如此。因为这会评估mylist.count < mylist.count,然后你会因TypeError.&nbsp;元组相互比较的实际方式是首先找到差异,然后通过检查相等性来完成。而且mylist.count == mylist.count不仅不会崩溃反而会返回True。因此,元组比较会转到下一个索引,在那里它将找到-3和-1。所以本质上你只是在做sorted(mylist,&nbsp;key=lambda&nbsp;x:&nbsp;-x,&nbsp;reverse=True)并且否定和reverse=True相互抵消,所以你得到相同的结果sorted(mylist,&nbsp;key=lambda&nbsp;x:&nbsp;x)要不就sorted(mylist)现在如何做对呢?一种方法是调用该函数(并删除否定):result&nbsp;=&nbsp;sorted(mylist,&nbsp;key=lambda&nbsp;x:&nbsp;(mylist.count(x),&nbsp;x),&nbsp;reverse=True)或者同时否定频率和价值,而不是reverse=True:result&nbsp;=&nbsp;sorted(mylist,&nbsp;key=lambda&nbsp;x:&nbsp;(-mylist.count(x),&nbsp;-x))另一种方法是利用排序的稳定性并使用两种更简单的排序(甚至可能比一种更复杂的排序更快):result&nbsp;=&nbsp;sorted(mylist,&nbsp;reverse=True) result.sort(key=mylist.count,&nbsp;reverse=True)请注意,这里我们不必调用mylist.count自己,因为它是键,它将为我们调用。就像你的“lambda 函数”确实被调用一样(只是不是其结果中的函数)。另请注意,我使用sorted后跟就地sort- 没有必要创建另一个列表并产生与之相关的成本。collections.Counter尽管在所有情况下,对于长列表,使用 a代替会更有效mylist.count,因为后者使解决方案采用 O(n&nbsp;2&nbsp;) 而不是 O(n log n)。

皈依舞

你可以试试 :from collections import Countercounts = Counter(mylist)new_list = sorted(mylist, key=lambda x: (counts[x], x), reverse=True)
随时随地看视频慕课网APP

相关分类

Python
我要回答