Como classificar Counter por valor? - Pitão

145

Além de compreender a lista de compreensão reversa da lista, existe uma maneira pitônica de classificar o contador por valor? Nesse caso, é mais rápido que isso:

>>> from collections import Counter
>>> x = Counter({'a':5, 'b':3, 'c':7})
>>> sorted(x)
['a', 'b', 'c']
>>> sorted(x.items())
[('a', 5), ('b', 3), ('c', 7)]
>>> [(l,k) for k,l in sorted([(j,i) for i,j in x.items()])]
[('b', 3), ('a', 5), ('c', 7)]
>>> [(l,k) for k,l in sorted([(j,i) for i,j in x.items()], reverse=True)]
[('c', 7), ('a', 5), ('b', 3)
alvas
fonte

Respostas:

251

Use o Counter.most_common()método , ele classificará os itens para você :

>>> from collections import Counter
>>> x = Counter({'a':5, 'b':3, 'c':7})
>>> x.most_common()
[('c', 7), ('a', 5), ('b', 3)]

Isso será feito da maneira mais eficiente possível; se você pedir um N superior em vez de todos os valores, a heapqserá usado em vez de uma classificação direta:

>>> x.most_common(1)
[('c', 7)]

Fora dos contadores, a classificação sempre pode ser ajustada com base em uma keyfunção; .sort()e sorted()ambos recebem chamadas que permitem especificar um valor no qual classificar a sequência de entrada; sorted(x, key=x.get, reverse=True)daria a você a mesma classificação que x.most_common(), mas retornará apenas as chaves, por exemplo:

>>> sorted(x, key=x.get, reverse=True)
['c', 'a', 'b']

ou você pode classificar apenas os (key, value)pares de valores fornecidos :

>>> sorted(x.items(), key=lambda pair: pair[1], reverse=True)
[('c', 7), ('a', 5), ('b', 3)]

Veja o tutorial de classificação do Python para obter mais informações.

Martijn Pieters
fonte
30

Uma boa adição à resposta @MartijnPieters é recuperar um dicionário classificado por ocorrência, uma vez que Collections.most_commonretorna apenas uma tupla. Costumo associar isso a uma saída json para arquivos de log úteis:

from collections import Counter, OrderedDict

x = Counter({'a':5, 'b':3, 'c':7})
y = OrderedDict(x.most_common())

Com a saída:

OrderedDict([('c', 7), ('a', 5), ('b', 3)])
{
  "c": 7, 
  "a": 5, 
  "b": 3
}
Hooked
fonte
10

Sim:

>>> from collections import Counter
>>> x = Counter({'a':5, 'b':3, 'c':7})

Usando a chave de palavra-chave classificada e uma função lambda:

>>> sorted(x.items(), key=lambda i: i[1])
[('b', 3), ('a', 5), ('c', 7)]
>>> sorted(x.items(), key=lambda i: i[1], reverse=True)
[('c', 7), ('a', 5), ('b', 3)]

Isso funciona para todos os dicionários. No entanto, Counterpossui uma função especial que já fornece os itens classificados (do mais frequente para o menos frequente). É chamado most_common():

>>> x.most_common()
[('c', 7), ('a', 5), ('b', 3)]
>>> list(reversed(x.most_common()))  # in order of least to most
[('b', 3), ('a', 5), ('c', 7)]

Você também pode especificar quantos itens deseja ver:

>>> x.most_common(2)  # specify number you want
[('c', 7), ('a', 5)]
Inbar Rose
fonte
Outra maneira de reverter tipo é para definir a função chave paralamda i: -i[1]
Steinar Lima
4

Classificação mais geral, em que a keypalavra - chave define o método de classificação, menos antes do tipo numérico indicar descendente:

>>> x = Counter({'a':5, 'b':3, 'c':7})
>>> sorted(x.items(), key=lambda k: -k[1])  # Ascending
[('c', 7), ('a', 5), ('b', 3)]
Alex Seam
fonte
2
A keypalavra-chave define o método de classificação, de menos antes de tipo numéricos indicam descendente
Alex Seam