Сортировка списка по частоте появления в списке
У меня есть список целых чисел (или может быть четными строками), которые я бы хотел отсортировать по частоте вхождений в Python, например:
a = [1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5]
Здесь элемент 5
появляется 4 раза в списке, 4
появляется 3 раза. Таким образом, отсортированный список результатов будет:
result = [5, 5, 5, 5, 3, 3, 3, 4, 4, 4, 1, 1, 2]
Я попробовал использовать a.count()
, но он дает количество элементов вхождения.
Я хотел бы отсортировать его. Любая идея, как это сделать?
Спасибо
Ответы
Ответ 1
from collections import Counter
print [item for items, c in Counter(a).most_common() for item in [items] * c]
# [5, 5, 5, 5, 3, 3, 3, 4, 4, 4, 1, 1, 2]
Или даже лучше (эффективная) реализация
from collections import Counter
from itertools import repeat, chain
print list(chain.from_iterable(repeat(i, c) for i,c in Counter(a).most_common()))
# [5, 5, 5, 5, 3, 3, 3, 4, 4, 4, 1, 1, 2]
или
from collections import Counter
print sorted(a, key=Counter(a).get, reverse=True)
# [5, 5, 5, 5, 3, 3, 3, 4, 4, 4, 1, 1, 2]
Если вы предпочитаете сортировку на месте
a.sort(key=Counter(a).get, reverse=True)
Ответ 2
In [15]: a = [1,1,2,3,3,3,4,4,4,5,5,5,5]
In [16]: counts = collections.Counter(a)
In [17]: list(itertools.chain.from_iterable([[k for _ in range(counts[k])] for k in sorted(counts, key=counts.__getitem__, reverse=True)]))
Out[17]: [5, 5, 5, 5, 3, 3, 3, 4, 4, 4, 1, 1, 2]
В качестве альтернативы:
answer = []
for k in sorted(counts, key=counts.__getitem__, reverse=True):
answer.extend([k for _ in range(counts[k])])
Конечно, [k for _ in range(counts[k])]
можно заменить на [k]*counts[k]
.
Таким образом, строка 17 становится
list(itertools.chain.from_iterable([[k]*counts[k] for k in sorted(counts, key=counts.__getitem__, reverse=True)]))
Ответ 3
Используя Python 3.3 и встроенную функцию sorted, счетчик как ключ:
>>> a = [1,1,2,3,3,3,4,4,4,5,5,5,5]
>>> sorted(a,key=a.count)
[2, 1, 1, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5]
>>> sorted(a,key=a.count,reverse=True)
[5, 5, 5, 5, 3, 3, 3, 4, 4, 4, 1, 1, 2]
Ответ 4
Не интересный способ...
a = [1,1,2,3,3,3,4,4,4,5,5,5,5]
from collections import Counter
result = []
for v, times in sorted(Counter(a).iteritems(), key=lambda x: x[1], reverse=True):
result += [v] * times
Один вкладыш:
reduce(lambda a, b: a + [b[0]] * b[1], sorted(Counter(a).iteritems(), key=lambda x: x[1], reverse=True), [])