Bagaimana cara mengurutkan Counter berdasarkan nilai? - python

154

Selain melakukan pemahaman daftar terbalik, apakah ada cara pythonic untuk mengurutkan Counter berdasarkan nilai? Jika demikian, lebih cepat dari ini:

>>> 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)
alva
sumber

Jawaban:

271

Gunakan Counter.most_common()metode ini , ini akan mengurutkan item untuk Anda :

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

Ini akan melakukannya dengan cara yang seefisien mungkin; jika Anda meminta Top N dan bukan semua nilai, a heapqdigunakan sebagai pengganti pengurutan lurus:

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

Di luar penghitung, pengurutan selalu dapat disesuaikan berdasarkan keyfungsi; .sort()dan sorted()keduanya menerima callable yang memungkinkan Anda menentukan nilai untuk mengurutkan urutan input; sorted(x, key=x.get, reverse=True)akan memberi Anda pengurutan yang sama seperti x.most_common(), tetapi hanya mengembalikan kunci, misalnya:

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

atau Anda dapat mengurutkan hanya pada (key, value)pasangan nilai yang diberikan :

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

Lihat cara penyortiran Python untuk informasi lebih lanjut.

Martijn Pieters
sumber
33

Tambahan yang bagus untuk jawaban @MartijnPieters adalah mendapatkan kembali kamus yang diurutkan berdasarkan kejadian karena Collections.most_commonhanya mengembalikan tupel. Saya sering memasangkan ini dengan output json untuk file log yang berguna:

from collections import Counter, OrderedDict

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

Dengan keluaran:

OrderedDict([('c', 7), ('a', 5), ('b', 3)])
{
  "c": 7, 
  "a": 5, 
  "b": 3
}
Doyan
sumber
11

Iya:

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

Menggunakan kunci kata kunci yang diurutkan dan fungsi 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)]

Ini berfungsi untuk semua kamus. Namun Countermemiliki fungsi khusus yang sudah memberi Anda item yang diurutkan (dari yang paling sering, hingga paling jarang). Ini disebut 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)]

Anda juga dapat menentukan berapa banyak item yang ingin Anda lihat:

>>> x.most_common(2)  # specify number you want
[('c', 7), ('a', 5)]
Inbar Rose
sumber
Cara lain untuk membalikkan urutan adalah dengan mengatur fungsi kunci kelamda i: -i[1]
Steinar Lima
4

Urutan yang lebih umum, di mana keykata kunci menentukan metode pengurutan, minus sebelum tipe numerik menunjukkan menurun:

>>> 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
sumber
2
Kata keykunci mendefinisikan metode pengurutan, minus sebelum tipe numerik menunjukkan turun
Alex Seam