Jak sortować licznik według wartości? - pyton

144

Czy istnieje pythoniczny sposób sortowania licznika według wartości, poza wykonywaniem poleceń listowych z odwróconym rozumieniem listowym? Jeśli tak, jest to szybsze niż to:

>>> 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
źródło

Odpowiedzi:

251

Użyj Counter.most_common()metody , ona posortuje elementy za Ciebie :

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

Zrobi to w najbardziej efektywny sposób; jeśli poprosisz o górne N zamiast wszystkich wartości, heapqzamiast sortowania prostego zostanie użyte a:

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

Poza licznikami sortowanie można zawsze dostosować na podstawie keyfunkcji; .sort()i sorted()oba pobierają wywoływalne, co pozwala określić wartość, według której ma być sortowana sekwencja wejściowa; sorted(x, key=x.get, reverse=True)dałoby to samo sortowanie, co x.most_common(), ale zwraca tylko klucze, na przykład:

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

lub możesz sortować tylko według podanych wartości (key, value)par:

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

Aby uzyskać więcej informacji, zobacz instrukcje sortowania w Pythonie .

Martijn Pieters
źródło
30

Dość fajnym dodatkiem do odpowiedzi @MartijnPieters jest odzyskanie słownika posortowanego według wystąpienia, ponieważ Collections.most_commonzwraca tylko krotkę. Często łączę to z wyjściem json dla przydatnych plików dziennika:

from collections import Counter, OrderedDict

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

Z wyjściem:

OrderedDict([('c', 7), ('a', 5), ('b', 3)])
{
  "c": 7, 
  "a": 5, 
  "b": 3
}
Haczykowaty
źródło
10

Tak:

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

Używając posortowanego klucza słowa kluczowego i funkcji 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)]

Działa to dla wszystkich słowników. Jednak Counterma specjalną funkcję, która już daje posortowane elementy (od najczęstszych do najrzadziej). Nazywa się 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)]

Możesz również określić, ile elementów chcesz zobaczyć:

>>> x.most_common(2)  # specify number you want
[('c', 7), ('a', 5)]
Inbar Rose
źródło
Innym sposobem odwrócenia sortowania jest ustawienie funkcji kluczowej nalamda i: -i[1]
Steinar Lima
4

Bardziej ogólne sortowanie, gdzie keysłowo kluczowe określa metodę sortowania, minus przed typem liczbowym wskazuje malejąco:

>>> 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
źródło
2
keyKluczowe określa sposób sortowania, minus przed typu numerycznego wskazują na malejące
Alex szew