问题
How to sort a tuple of elements in python, first on the basis of value and then on the basis of key. Consider the program in which I am taking input from the user as a string. I want to find out the count of each character and print the 3 most common characters in a string.
#input string
strr=list(raw_input())
count=dict()
#store the count of each character in dictionary
for i in range(len(strr)):
count[strr[i]]=count.get(strr[i],0)+1
#hence we can't perform sorting on dict so convert it into tuple
temp=list()
t=count.items()
for (k,v) in t:
temp.append((v,k))
temp.sort(reverse=True)
#print 3 most common element
for (v,k) in temp[:3]:
print k,v
on giving the i/p -aabbbccde
Output of the above code is:
3 b
2 c
2 a
But I want the output as:
3 b
2 a
2 c
回答1:
Sort a list of tuples, the first value in descending order (reverse=True
) and the second value in ascending order (reverse=False
, by default). Here is a MWE.
lists = [(2, 'c'), (2, 'a'), (3, 'b')]
result = sorted(lists, key=lambda x: (-x[0], x[1])) # -x[0] represents descending order
print(result)
# Output
[(3, 'b'), (2, 'a'), (2, 'c')]
It is straightforward to use collections.Counter to count each letter's frequency in a string.
import collections
s = 'bcabcab'
# If you don't care the order, just use `most_common`
#most_common = collections.Counter(s).most_common(3)
char_and_frequency = collections.Counter(s)
result = sorted(char_and_frequency.items(), key=lambda x:(-x[1], x[0]))[:3] # sorted by x[1] in descending order, x[0] in ascending order
print(result)
# Output
[('b', 3), ('a', 2), ('c', 2)]
回答2:
As a general solution for "sort by value descending then by key ascending" you can use itertools.groupby
:
import itertools
from operator import itemgetter
def sort_by_value_then_key(count_dict):
first_level_sorted = sorted(count_dict.items(), key=itemgetter(1), reverse=True)
for _, group in itertools.groupby(first_level_sorted,itemgetter(1)):
for pair in sorted(group):
yield pair
strr=list("aabbccdef")
count=dict()
#store the count of each character in dictionary
for i in range(len(strr)):
count[strr[i]]=count.get(strr[i],0)+1
temp = list(sort_by_value_then_key(count))
for (letter, freq) in temp[:3]:
print letter, freq
Output:
a 2
b 2
c 2
since you are using integers @sparkandshine's solution of sorting by the negative number will probably be easier to work with but this is much more generalized.
来源:https://stackoverflow.com/questions/37513551/how-to-sort-tuple-element-first-on-the-basis-of-key-and-then-on-the-basis-of-val