web-dev-qa-db-fra.com

Comment trier Counter par valeur? - python

Existe-t-il un moyen pythonique de trier Counter par valeur? Si c'est le cas, c'est plus rapide que ça:

>>> 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)
99
alvas

Utilisez la méthode Counter.most_common()) , elle triera les éléments pour vous :

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

Il le fera de la manière la plus efficace possible. si vous demandez un Top N au lieu de toutes les valeurs, un heapq est utilisé à la place d'un tri simple:

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

En dehors des compteurs, le tri peut toujours être ajusté en fonction d'une fonction key; .sort() et sorted() prennent tous deux appelable pour vous permettre de spécifier une valeur sur laquelle trier la séquence d'entrée; sorted(x, key=x.get, reverse=True) vous donnerait le même tri que x.most_common(), mais ne renverrait que les clés, par exemple:

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

ou vous pouvez trier uniquement sur la valeur donnée (key, value) paires:

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

Voir le Guide de tri Python pour plus d'informations.

181
Martijn Pieters

Un ajout plutôt sympa à @ MartijnPieters La réponse est de récupérer un dictionnaire trié par occurrence puisque Collections.most_common ne renvoie que un tuple. Je couple souvent ceci avec une sortie JSON pour les fichiers de log utiles:

from collections import Counter, OrderedDict

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

Avec la sortie:

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

Oui:

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

En utilisant la clé de mot de passe triée et une fonction 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)]

Cela fonctionne pour tous les dictionnaires. Cependant, Counter a une fonction spéciale qui vous donne déjà les éléments triés (du plus fréquent au moins fréquent). Cela s'appelle 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)]

Vous pouvez également spécifier le nombre d'éléments que vous souhaitez voir:

>>> x.most_common(2)  # specify number you want
[('c', 7), ('a', 5)]
9
Inbar Rose

Tri plus général, où le mot clé key définit la méthode de tri, le signe moins avant que le type numérique indique un ordre décroissant:

>>> x = Counter({'a':5, 'b':3, 'c':7})
>>> sorted(x.items(), key=lambda k: -k[1])  # Ascending
[('c', 7), ('a', 5), ('b', 3)]
1
Alex Seam