pythondictionaryfor-loopif-statementsorteddictionary

how to find the most popular letter in a string that also has the lowest ascii value


Implement the function most_popular_character(my_string), which gets the string argument my_string and returns its most frequent letter. In case of a tie, break it by returning the letter of smaller ASCII value. Note that lowercase and uppercase letters are considered different (e.g., ‘A’ < ‘a’). You may assume my_string consists of English letters only, and is not empty.

Example 1: >>> most_popular_character("HelloWorld") >>> 'l'

Example 2: >>> most_popular_character("gggcccbb") >>> 'c'
Explanation: cee and gee appear three times each (and bee twice), but cee precedes gee lexicographically.

Hints (you may ignore these):

def most_popular_character(my_string):
   char_count = {} # define dictionary
   for c in my_string:
      if c in char_count: #if c is in the dictionary:
         char_count[c] = 1
      else: # if c isn't in the dictionary - create it and put 1
         char_count[c] = 1

   sorted_chars = sorted(char_count) # sort the dictionary
   char_count = char_count.keys() # place the dictionary in a list

   max_per = 0
   for i in range(len(sorted_chars) - 1):
      if sorted_chars[i] >= sorted_chars[i+1]:
         max_per = sorted_chars[i]
         break
   return max_per

my function returns 0 right now, and I think the problem is in the last for loop and if statement - but I can't figure out what the problem is..

If you have any suggestions on how to adjust the code it would be very appreciated!


Solution

  • Your dictionary didn't get off to a good start by you forgetting to add 1 to the character count, instead you are resetting to 1 each time. Have a look here to get the gist of getting the maximum value from a dict: https://datagy.io/python-get-dictionary-key-with-max-value/

    def most_popular_character(my_string):
        # NOTE: you might want to convert the entire sting to upper or lower case, first, depending on the use
        # e.g. my_string = my_string.lower()
        char_count = {} # define dictionary
        for c in my_string:
           if c in char_count: #if c is in the dictionary:
              char_count[c] += 1 # add 1 to it
           else: # if c isn't in the dictionary - create it and put 1
              char_count[c] = 1
    
        # Never under estimate the power of print in debugging
        print(char_count)
    
        # max(char_count.values()) will give the highest value
        # But there may be more than 1 item with the highest count, so get them all
        max_keys = [key for key, value in char_count.items() if value == max(char_count.values())]
    
        # Choose the lowest by sorting them and pick the first item
        low_item = sorted(max_keys)[0]
    
        return low_item, max(char_count.values())
    
    print(most_popular_character("HelloWorld"))
    print(most_popular_character("gggcccbb"))
    print(most_popular_character("gggHHHAAAAaaaccccbb 12 3"))
    

    Result:

    {'H': 1, 'e': 1, 'l': 3, 'o': 2, 'W': 1, 'r': 1, 'd': 1}
    ('l', 3)
    {'g': 3, 'c': 3, 'b': 2}
    ('c', 3)
    {'g': 3, 'H': 3, 'A': 4, 'a': 3, 'c': 4, 'b': 2, ' ': 2, '1': 1, '2': 1, '3': 1}
    ('A', 4)
    

    So: l and 3, c and 3, A and 4