How can I sort the results of Counter.mostCommon by the counter, and then the value?
My original code:
from collections import Counter
for counter in Counter("abcdefg").most_common(3):
print(counter[0], counter[1])
The output is different every time, since each value has a count of 1. Sometimes it is
a 1
b 1
e 1
sometimes
b 1
d 1
f 1
etc.
I want this:
a 1
b 1
c 1
I've also tried sorting the resulting tuples::
from collections import Counter
for counter in sorted(Counter("abcdefg").most_common(3), key=lambda x: x[0]): print(counter[0], counter[1])
and sorting the string
from collections import Counter
for counter in Counter(sorted("abcdefg")).most_common(3): print(counter[0], counter[1])
but I get the same unpredictable results
The problem here is that Counter dicts are unordered, and most_common doesn't care about the keys. To accomplish this, you need to sort the dict's items and then pull off the 3 most common.
counter = Counter('abcdef')
most_common = sorted(counter.items(), key=lambda pair: (-pair[1], pair[0]))
This will sort on -pair[1] (the counts) first. Higher counts will appear first because of the negative. Next we sort on pair[0] (the key) which will order lexicographically in normal increasing order.
From here, you need to slice off the items that you want ...
most_common[:3]
Alternatively, we can take a page out of the source code and re-implement most_common to take the keys into account.
import heapq as _heapq
def most_common(counter, n=None):
'''List the n most common elements and their counts from the most
common to the least. If n is None, then list all element counts.
>>> Counter('abcdeabcdabcaba').most_common(3)
[('a', 5), ('b', 4), ('c', 3)]
'''
# Emulate Bag.sortedByCount from Smalltalk
sort_key = lambda pair: (-pair[1], pair[0])
if n is None:
return sorted(counter.iteritems(), key=sort_key)
return _heapq.nsmallest(n, counter.iteritems(), key=sort_key)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With