Minuet
Minuet

Reputation: 93

Sorting a dictionary by its value in descending order and its key in ascending order

I'm tasked to extract all unique characters in a string (excluding whitespace) and sorting it based on the amount of appearances of a given character in the string (so in descending sort order) and in case of ties, sort by their ASCII code.

Example:

Input: 'I am a cat'

Output: 'aIcmt'

The problem I'm facing particularly is the fact that if I use this line of code for sorting:

char_list = sorted(char_dict.items(), key = lambda x: (x[1],ord(x[0])), reverse = True)

It reverse sort even the ord(x[0]) which sorts the char part of the dictionary though I only want to sort the value of occurences of the characters.

Here is my code for references:

string_list = [char for char in string]
string_list = [char for char in string_list if char != ' ']

print(string_list)

char_dict = {}

for char in string_list:
    if char not in char_dict:
        char_dict[char] = 0
    else:
        char_dict[char] += 1

char_list = sorted(char_dict.items(), key = lambda x: (x[1],ord(x[0])), reverse = True)
print(char_list)

for i in char_list:
    print(i[0], end = '')


Upvotes: 3

Views: 1651

Answers (3)

niraj
niraj

Reputation: 18218

You can try combination of Counter, sorted, and join.

from collections import Counter

input_str = 'I am a cat'

# use counter to get count of each character including white space
t = list(Counter(input_str).most_common())

# sort on count on reverse and ascii on ascending when ties 
t = sorted(t, key=lambda i: (-i[1], i[0])) 

# exclude white space and join remaining sorted characters
res = ''.join(i[0] for i in t if i[0] != ' ') 

print(res)

Output:

aIcmt

Upvotes: 2

Iain Shelvington
Iain Shelvington

Reputation: 32304

collections.Counter takes an iterable (strings are iterable and will return each character one at a time when iterated over) and will return a dictionary-like object from which you can get each entry sorted by the number of occurrences using most_common

from collections import Counter
counter = Counter(string)
print(''.join(x[0] for x in counter.most_common()))

EDIT:

As Mad Physicist says, to exclude spaces from being counted you can pass a generator to Counter

counter = Counter(c for c in string if c != ' ')

Upvotes: 2

Joao_Lacerda
Joao_Lacerda

Reputation: 1

are you allowed to do this task without the use of dictionary? if yes you could try this way : use a counter for every letter, them check the chars of the string without the space, adding a counter(use a switch) to the letter that matches, after that compose a string beggining with "" them add letters that have more than 0 counters(you could either sort the int values of the counters to do it in order or check before adding wich position the letter will go, sorting is probably easier) after that you will have what you want.

Upvotes: -2

Related Questions