Pythonでリストを頻度でソートできる方法はありますか?
例えば、
[1,2,3,4,3,3,3,6,7,1,1,9,3,2]
上記のリストは、値の頻度の順に並べ替えられ、次のリストが作成されます。ここで、頻度が最も高いアイテムが前に配置されます。
[3,3,3,3,3,1,1,1,2,2,4,6,7,9]
これはcollections.Counter
:
counts = collections.Counter(lst)
new_list = sorted(lst, key=lambda x: -counts[x])
または、ラムダなしで2行目を書くこともできます。
counts = collections.Counter(lst)
new_list = sorted(lst, key=counts.get, reverse=True)
同じ頻度の複数の要素がある場合andそれらがグループ化されたままであることを気にかけている場合、カウントだけでなくvalueも含めるようにソートキーを変更することでそれを行うことができます=:
counts = collections.Counter(lst)
new_list = sorted(lst, key=lambda x: (counts[x], x), reverse=True)
l = [1,2,3,4,3,3,3,6,7,1,1,9,3,2]
print sorted(l,key=l.count,reverse=True)
[3, 3, 3, 3, 3, 1, 1, 1, 2, 2, 4, 6, 7, 9]
楽しみのためにこれを練習していました。このソリューションでは、時間の複雑さが軽減されます。
from collections import defaultdict
lis = [1,2,3,4,3,3,3,6,7,1,1,9,3,2]
dic = defaultdict(int)
for num in lis:
dic[num] += 1
s_list = sorted(dic, key=dic.__getitem__, reverse=True)
new_list = []
for num in s_list:
for rep in range(dic[num]):
new_list.append(num)
print(new_list)
ダブルコンパレータを使用したい場合。
例:頻度でリストを降順で並べ替えます。衝突の場合は、小さい方が最初に表示されます。
import collections
def frequency_sort(a):
f = collections.Counter(a)
a.sort(key = lambda x:(-f[x], x))
return a
Counter
を使用して各アイテムの数を取得できます。そのmost_common
メソッドでソートされた順序で取得し、リスト内包表記を使用して再度展開します
>>> lst = [1,2,3,4,3,3,3,6,7,1,1,9,3,2]
>>>
>>> from collections import Counter
>>> [n for n,count in Counter(lst).most_common() for i in range(count)]
[3, 3, 3, 3, 3, 1, 1, 1, 2, 2, 4, 6, 7, 9]