Comment trier le compteur par valeur? - python

145

À part faire des compréhensions de liste de compréhension de liste inversée, existe-t-il un moyen pythonique de trier Counter par valeur? Si c'est le cas, c'est plus rapide que cela:

>>> 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
la source

Réponses:

251

Utilisez la Counter.most_common()méthode , 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, a heapqest utilisé au lieu d'un tri simple:

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

En dehors des compteurs, le tri peut toujours être ajusté en fonction d'une keyfonction; .sort()et sorted()tous deux prennent appelable qui vous permet 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 les (key, value)paires de valeurs données :

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

Consultez le guide du tri Python pour plus d'informations.

Martijn Pieters
la source
30

Un ajout plutôt intéressant à la réponse de @MartijnPieters est de récupérer un dictionnaire trié par occurrence car Collections.most_commonne renvoie qu'un tuple. Je couple souvent cela avec une sortie json pour les fichiers journaux pratiques:

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
}
Accroché
la source
10

Oui:

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

À l'aide de la clé de mot-clé triée et d'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 Countera une fonction spéciale qui vous donne déjà les éléments triés (du plus fréquent au moins fréquent). Ça 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)]
Rose Inbar
la source
Une autre façon d'inverser le tri consiste à définir la fonction clé surlamda i: -i[1]
Steinar Lima
4

keyTri plus général, où le mot - clé définit la méthode de tri, moins avant que le type numérique indique 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)]
Alex Seam
la source
2
Le keymot clé définit la méthode de tri, moins avant que le type numérique indique décroissant
Alex Seam