Python program to find the most frequent letter in a textPangrams CodeEval challengeImprove efficiency for...

Did 20% of US soldiers in Vietnam use heroin, 95% of whom quit afterwards?

Alignment: "Breaking out" of environment (enumerate / minipage)

Are these reasonable traits for someone with autism?

Is the field of q-series 'dead'?

The art of clickbait captions

Why aren't space telescopes put in GEO?

Need to understand my home electrical meter to see why bill is so high and/or if neighbor is on same meter

How to know if a folder is a symbolic link?

What could a self-sustaining lunar colony slowly lose that would ultimately prove fatal?

Why didn't Project Mercury advance to an orbital flight on their second mission?

What is a Centaur Thief's climbing speed?

Why does this if-statement combining assignment and an equality check return true?

Should breaking down something like a door be adjudicated as an attempt to beat its AC and HP, or as an ability check against a set DC?

Which melee weapons have the Two-Handed property, but lack Heavy and Special?

Teacher help me explain this to my students

Would Jetfuel for a modern jet like an F-16 or a F-35 be producable in the WW2 era?

Why do most published works in medical imaging try to reduce false positives?

Why is this Simple Puzzle impossible to solve?

What are the real benefits of using Salesforce DX?

number headings

Is Jon Snow the last of his House?

Website returning plaintext password

Boss wants me to falsify a report. How should I document this unethical demand?

How to deal with a colleague who is being aggressive?



Python program to find the most frequent letter in a text


Pangrams CodeEval challengeImprove efficiency for finding word frequency in text“Word-Target” Puzzle Solver in JavaPangrams python implementationProject Euler 22: Names scores alternativeThe veiled guise of binary and stringProject Euler 22: Names scores using dictionaryCount the number of occurences of X's within a range in JavaCaesar Cipher in Haskell, on every other characterWrite a function that takes a list of strings an prints them, one per line, in a rectangular frame. slight change needed






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







4












$begingroup$


Given a text like "Hello World!" the program outputs the most frequent letter, in this case the "l".



If there are two letters with the same frequency, it outputs the first in alphabetical order, for example in the text "One" it outputs "e".



In addition upper and lower letters are counted as the same letter.



How could be this code improved?



def most_frequent_letter(text: str) -> str:

letters_dict = {}
text = text.lower()
text = re.sub("[^a-z]","",text)

for letter in text:
if letter in letters_dict:
letters_dict[letter] += 1
else:
letters_dict[letter] = 1

value_to_key = collections.defaultdict(list)
for key_letter, frecuency_value in letters_dict.items():
value_to_key[frecuency_value].append(key_letter)

letters = list(value_to_key.values())
frecuencies = list(value_to_key.keys())
return (sorted(letters[frecuencies.index(max(frecuencies))])[0])









share|improve this question









$endgroup$



















    4












    $begingroup$


    Given a text like "Hello World!" the program outputs the most frequent letter, in this case the "l".



    If there are two letters with the same frequency, it outputs the first in alphabetical order, for example in the text "One" it outputs "e".



    In addition upper and lower letters are counted as the same letter.



    How could be this code improved?



    def most_frequent_letter(text: str) -> str:

    letters_dict = {}
    text = text.lower()
    text = re.sub("[^a-z]","",text)

    for letter in text:
    if letter in letters_dict:
    letters_dict[letter] += 1
    else:
    letters_dict[letter] = 1

    value_to_key = collections.defaultdict(list)
    for key_letter, frecuency_value in letters_dict.items():
    value_to_key[frecuency_value].append(key_letter)

    letters = list(value_to_key.values())
    frecuencies = list(value_to_key.keys())
    return (sorted(letters[frecuencies.index(max(frecuencies))])[0])









    share|improve this question









    $endgroup$















      4












      4








      4





      $begingroup$


      Given a text like "Hello World!" the program outputs the most frequent letter, in this case the "l".



      If there are two letters with the same frequency, it outputs the first in alphabetical order, for example in the text "One" it outputs "e".



      In addition upper and lower letters are counted as the same letter.



      How could be this code improved?



      def most_frequent_letter(text: str) -> str:

      letters_dict = {}
      text = text.lower()
      text = re.sub("[^a-z]","",text)

      for letter in text:
      if letter in letters_dict:
      letters_dict[letter] += 1
      else:
      letters_dict[letter] = 1

      value_to_key = collections.defaultdict(list)
      for key_letter, frecuency_value in letters_dict.items():
      value_to_key[frecuency_value].append(key_letter)

      letters = list(value_to_key.values())
      frecuencies = list(value_to_key.keys())
      return (sorted(letters[frecuencies.index(max(frecuencies))])[0])









      share|improve this question









      $endgroup$




      Given a text like "Hello World!" the program outputs the most frequent letter, in this case the "l".



      If there are two letters with the same frequency, it outputs the first in alphabetical order, for example in the text "One" it outputs "e".



      In addition upper and lower letters are counted as the same letter.



      How could be this code improved?



      def most_frequent_letter(text: str) -> str:

      letters_dict = {}
      text = text.lower()
      text = re.sub("[^a-z]","",text)

      for letter in text:
      if letter in letters_dict:
      letters_dict[letter] += 1
      else:
      letters_dict[letter] = 1

      value_to_key = collections.defaultdict(list)
      for key_letter, frecuency_value in letters_dict.items():
      value_to_key[frecuency_value].append(key_letter)

      letters = list(value_to_key.values())
      frecuencies = list(value_to_key.keys())
      return (sorted(letters[frecuencies.index(max(frecuencies))])[0])






      python beginner dictionary






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 8 hours ago









      enoyenoy

      25115




      25115






















          3 Answers
          3






          active

          oldest

          votes


















          4












          $begingroup$

          If you are going to use the collections module at all (as you did for collections.defaultdict), then why not use collections.Counter, which offers a most_common() method?






          share|improve this answer









          $endgroup$





















            4












            $begingroup$

            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]:
            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 if statement...




            # ...
            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?






            share|improve this answer











            $endgroup$





















              2












              $begingroup$

              There are many ways to do this shorter. For example, you can use the Counter class (in Python 2.7 or later):



              import collections
              s = "helloworld"
              print(collections.Counter(s).most_common(1)[0])


              If you don't have that, you can do the tally manually (2.5 or later has defaultdict):



              d = collections.defaultdict(int)
              for c in s:
              d[c] += 1
              print(sorted(d.items(), key=lambda x: x[1], reverse=True)[0])


              Having said that, there's nothing wrong with your implementation.



              NOTE - This prints the letter along with how many times it actually occurs.



              Hope this helps!






              share|improve this answer









              $endgroup$













              • $begingroup$
                Note that Counter(s).most_common(1)[0] does not satisfy the "alphabetical order in case of ties" requirement.
                $endgroup$
                – 200_success
                6 hours ago














              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "196"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: false,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f220927%2fpython-program-to-find-the-most-frequent-letter-in-a-text%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              4












              $begingroup$

              If you are going to use the collections module at all (as you did for collections.defaultdict), then why not use collections.Counter, which offers a most_common() method?






              share|improve this answer









              $endgroup$


















                4












                $begingroup$

                If you are going to use the collections module at all (as you did for collections.defaultdict), then why not use collections.Counter, which offers a most_common() method?






                share|improve this answer









                $endgroup$
















                  4












                  4








                  4





                  $begingroup$

                  If you are going to use the collections module at all (as you did for collections.defaultdict), then why not use collections.Counter, which offers a most_common() method?






                  share|improve this answer









                  $endgroup$



                  If you are going to use the collections module at all (as you did for collections.defaultdict), then why not use collections.Counter, which offers a most_common() method?







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 8 hours ago









                  200_success200_success

                  132k20160427




                  132k20160427

























                      4












                      $begingroup$

                      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]:
                      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 if statement...




                      # ...
                      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?






                      share|improve this answer











                      $endgroup$


















                        4












                        $begingroup$

                        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]:
                        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 if statement...




                        # ...
                        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?






                        share|improve this answer











                        $endgroup$
















                          4












                          4








                          4





                          $begingroup$

                          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]:
                          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 if statement...




                          # ...
                          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?






                          share|improve this answer











                          $endgroup$



                          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]:
                          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 if statement...




                          # ...
                          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?







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited 4 hours ago

























                          answered 7 hours ago









                          S0AndS0S0AndS0

                          5118




                          5118























                              2












                              $begingroup$

                              There are many ways to do this shorter. For example, you can use the Counter class (in Python 2.7 or later):



                              import collections
                              s = "helloworld"
                              print(collections.Counter(s).most_common(1)[0])


                              If you don't have that, you can do the tally manually (2.5 or later has defaultdict):



                              d = collections.defaultdict(int)
                              for c in s:
                              d[c] += 1
                              print(sorted(d.items(), key=lambda x: x[1], reverse=True)[0])


                              Having said that, there's nothing wrong with your implementation.



                              NOTE - This prints the letter along with how many times it actually occurs.



                              Hope this helps!






                              share|improve this answer









                              $endgroup$













                              • $begingroup$
                                Note that Counter(s).most_common(1)[0] does not satisfy the "alphabetical order in case of ties" requirement.
                                $endgroup$
                                – 200_success
                                6 hours ago


















                              2












                              $begingroup$

                              There are many ways to do this shorter. For example, you can use the Counter class (in Python 2.7 or later):



                              import collections
                              s = "helloworld"
                              print(collections.Counter(s).most_common(1)[0])


                              If you don't have that, you can do the tally manually (2.5 or later has defaultdict):



                              d = collections.defaultdict(int)
                              for c in s:
                              d[c] += 1
                              print(sorted(d.items(), key=lambda x: x[1], reverse=True)[0])


                              Having said that, there's nothing wrong with your implementation.



                              NOTE - This prints the letter along with how many times it actually occurs.



                              Hope this helps!






                              share|improve this answer









                              $endgroup$













                              • $begingroup$
                                Note that Counter(s).most_common(1)[0] does not satisfy the "alphabetical order in case of ties" requirement.
                                $endgroup$
                                – 200_success
                                6 hours ago
















                              2












                              2








                              2





                              $begingroup$

                              There are many ways to do this shorter. For example, you can use the Counter class (in Python 2.7 or later):



                              import collections
                              s = "helloworld"
                              print(collections.Counter(s).most_common(1)[0])


                              If you don't have that, you can do the tally manually (2.5 or later has defaultdict):



                              d = collections.defaultdict(int)
                              for c in s:
                              d[c] += 1
                              print(sorted(d.items(), key=lambda x: x[1], reverse=True)[0])


                              Having said that, there's nothing wrong with your implementation.



                              NOTE - This prints the letter along with how many times it actually occurs.



                              Hope this helps!






                              share|improve this answer









                              $endgroup$



                              There are many ways to do this shorter. For example, you can use the Counter class (in Python 2.7 or later):



                              import collections
                              s = "helloworld"
                              print(collections.Counter(s).most_common(1)[0])


                              If you don't have that, you can do the tally manually (2.5 or later has defaultdict):



                              d = collections.defaultdict(int)
                              for c in s:
                              d[c] += 1
                              print(sorted(d.items(), key=lambda x: x[1], reverse=True)[0])


                              Having said that, there's nothing wrong with your implementation.



                              NOTE - This prints the letter along with how many times it actually occurs.



                              Hope this helps!







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered 8 hours ago









                              JustinJustin

                              1




                              1












                              • $begingroup$
                                Note that Counter(s).most_common(1)[0] does not satisfy the "alphabetical order in case of ties" requirement.
                                $endgroup$
                                – 200_success
                                6 hours ago




















                              • $begingroup$
                                Note that Counter(s).most_common(1)[0] does not satisfy the "alphabetical order in case of ties" requirement.
                                $endgroup$
                                – 200_success
                                6 hours ago


















                              $begingroup$
                              Note that Counter(s).most_common(1)[0] does not satisfy the "alphabetical order in case of ties" requirement.
                              $endgroup$
                              – 200_success
                              6 hours ago






                              $begingroup$
                              Note that Counter(s).most_common(1)[0] does not satisfy the "alphabetical order in case of ties" requirement.
                              $endgroup$
                              – 200_success
                              6 hours ago




















                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Code Review Stack Exchange!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              Use MathJax to format equations. MathJax reference.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f220927%2fpython-program-to-find-the-most-frequent-letter-in-a-text%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown