How to write a function that takes a string and prints letters in decreasing order of frequency?

I went so far:

def most_frequent(string): d = dict() for key in string: if key not in d: d[key] = 1 else: d[key] += 1 return d print most_frequent('aabbbc') 

Return:

 {'a': 2, 'c': 1, 'b': 3} 

Now I need:

  • reverse pair
  • sort by number descending
  • print letters only

Should I convert this dictionary to tuples or list?

+4
source share
10 answers

Here is one line answer

 sortedLetters = sorted(d.iteritems(), key=lambda (k,v): (v,k)) 
+13
source

That should make it beautiful.

 def frequency_analysis(string): d = dict() for key in string: d[key] = d.get(key, 0) + 1 return d def letters_in_order_of_frequency(string): frequencies = frequency_analysis(string) # frequencies is of bounded size because number of letters is bounded by the dictionary, not the input size frequency_list = [(freq, letter) for (letter, freq) in frequencies.iteritems()] frequency_list.sort(reverse=True) return [letter for freq, letter in frequency_list] string = 'aabbbc' print letters_in_order_of_frequency(string) 
+5
source

This is what returns a list of tuples, not a dictionary:

 import operator if __name__ == '__main__': test_string = 'cnaa' string_dict = dict() for letter in test_string: if letter not in string_dict: string_dict[letter] = test_string.count(letter) # Sort dictionary by values, credits go here http://stackoverflow.com/questions/613183/sort-a-dictionary-in-python-by-the-value/613218#613218 ordered_answer = sorted(string_dict.items(), key=operator.itemgetter(1), reverse=True) print ordered_answer 
+3
source

Python 2.7 directly supports this use case:

 >>> from collections import Counter >>> Counter('abracadabra').most_common() [('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)] 
+3
source

chills42 lambda function wins, I think, but as an alternative, how about generating a dictionary with values ​​as keys instead?

 def count_chars(string): distinct = set(string) dictionary = {} for s in distinct: num = len(string.split(s)) - 1 dictionary[num] = s return dictionary def print_dict_in_reverse_order(d): _list = d.keys() _list.sort() _list.reverse() for s in _list: print d[s] 
+2
source

EDIT . This will do what you want. I steal chills42 and add another:

 sortedLetters = sorted(d.iteritems(), key=lambda (k,v): (v,k)) sortedString = ''.join([c[0] for c in reversed(sortedLetters)]) 

------------ original answer ------------

To print the sorted line, add another line to chills42 single line:

 ''.join(map(lambda c: str(c[0]*c[1]), reversed(sortedLetters))) 

This displays "bbbaac"

If you want to use single letters, use "bac":

 ''.join([c[0] for c in reversed(sortedLetters)]) 
+2
source
 from collections import defaultdict def most_frequent(s): d = defaultdict(int) for c in s: d[c] += 1 return "".join([ k for k, v in sorted( d.iteritems(), reverse=True, key=lambda (k, v): v) ]) 

EDIT:

here is my one liner:

 def most_frequent(s): return "".join([ c for frequency, c in sorted( [(s.count(c), c) for c in set(s)], reverse=True ) ]) 
+2
source

Here is the code for your most_frequent function:

 >>> a = 'aabbbc' >>> {i: a.count(i) for i in set(a)} {'a': 2, 'c': 1, 'b': 3} 

this particular syntax is for py3k, but it's easy to write something like that using the syntax of previous versions. it seems to me more readable than yours.

+1
source
 def reversedSortedFrequency(string) from collections import defaultdict d = defaultdict(int) for c in string: d[c]+=1 return sorted([(v,k) for k,v in d.items()], key=lambda (k,v): -k) 
0
source

Here is the corrected version (thanks for pointing out the errors)

 def frequency(s): return ''.join( [k for k, v in sorted( reduce( lambda d, c: d.update([[c, d.get(c, 0) + 1]]) or d, list(s), dict()).items(), lambda a, b: cmp(a[1], b[1]), reverse=True)]) 

I think using reduce makes a difference in this resolution compared to others ...

In action:

 >>> from frequency import frequency >>> frequency('abbbccddddxxxyyyyyz') 'ydbxcaz' 

This one includes key extraction (and counting them) as well !!! Another nice property is the initialization of the dictionary on the same line :)

Also: no includes , just embedded.

The reduce function is pretty hard to wrap around, and the meaning of the dictionary in lambda also a bit cumbersome in python, but, well, it works!

0
source

All Articles