For the most part your code is okay, however, reading what it is that you want it to do here's what I came up with...
#!/usr/bin/env python3 import re import typing # def most_frequent_letter(text: str) -> typing.Tuple[int, list]: ## Use above if returning an int and list instead of int and string def most_frequent_letter(text: str) -> typing.Tuple[int, str]list]: text = re.sub('[^a-z]', '', text.replace(' ', '').lower()) letter_counts = {} for letter in text: letter_counts[letter] = letter_counts.get(letter, 0) + 1 counted_letters = {} for letter, counter in letter_counts.items(): counted_letters[counter] = counted_letters.get(counter, []) + [letter] max_key = max(counted_letters.keys()) return max_key, sorted(counted_letters[max_key]) if __name__ == '__main__': counted, letters = most_frequent_letter('spam ham jello spam') print("{counted} -> {letter}".format( counted = counted, letter = letters[0])) ... while I don't know that it's an improvement overall it does return results that may be of use...
3 -> a Note if ya want the whole list use the following instead under that last
ifstatement...
# ... print("{counted} -> {letters}".format( counted = counted, letters = letters)) # ... Should output... # 3 -> ['a', 'm'] ... while also not counting spaces as letters; which is the only thing that seemed missing from your implementation.
I didn't see any need to use if statements (within the function) so didn't include'em, because dictionaries have a handy get method that allows for defaulting nonexistent key value pares. And I didn't see any use in using collections though it was tempting to use @200_success's suggestion.
One thing about your code that I do still question though is why are ya wrapping the returned value within parentheses?