4

I've been solving problems in checkio.com and one of the questions was: "Write a function to find the letter which occurs the maximum number of times in a given string"

The top solution was:

import string

def checkio(text):
    """
    We iterate through latin alphabet and count each letter in the text.
    Then 'max' selects the most frequent letter.
    For the case when we have several equal letter,
    'max' selects the first from they.
    """
    text = text.lower()
    return max(string.ascii_lowercase, key=text.count)

I didn't understand what text.count is when it is used as the key in the max function.

Edit: Sorry for not being more specific. I know what the program does as well as the function of str.count(). I want to know what text.count is. If .count is a method then shouldn't it be followed by braces?

waivek
  • 193
  • 1
  • 5

3 Answers3

4

The key=text.count is what is counting the number of times all the letters appear in the string, then you take the highest number of all those numbers to get the most frequent letter that has appeared.

When the following code is run, the result is e, which is, if you count, the most frequent letter.

import string

def checkio(text):
    """
    We iterate through latin alphabet and count each letter in the text.
    Then 'max' selects the most frequent letter.
    For the case when we have several equal letter,
    'max' selects the first from they.
    """
    text = text.lower()
    return max(string.ascii_lowercase, key=text.count)

print checkio('hello my name is heinst')
heinst
  • 8,520
  • 7
  • 41
  • 77
2

A key function in max() is called for each element to provide an alternative to determine the maximum by, which in this case isn't all that efficient.

Essentially, the line max(string.ascii_lowercase, key=text.count) can be translated to:

max_character, max_count = None, -1
for character in string.ascii_lowercase:
    if text.count(character) > max_count:
        max_character = character
return max_character

where str.count() loops through the whole of text counting how often character occurs.

You should really use a multiset / bag here instead; in Python that's provided by the collections.Counter() type:

max_character = Counter(text.lower()).most_common(1)[0][0]

The Counter() takes O(N) time to count the characters in a string of length N, then to find the maximum, another O(K) to determine the highest count, where K is the number of unique characters. Asymptotically speaking, that makes the whole process take O(N) time.

The max() approach takes O(MN) time, where M is the length of string.ascii_lowercase.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0

Use the Counter function from the collections module.

>>> import collections
>>> word = "supercalafragalistic"
>>> c = collections.Counter(word)
>>> c.most_common()
[('a', 4), ('c', 2), ('i', 2), ('l', 2), ('s', 2), ('r', 2), ('e', 1), ('g', 1), ('f', 1), ('p', 1), ('u', 1), ('t', 1)]
>>> c.most_common()[0]
('a', 4)
jumbopap
  • 3,969
  • 5
  • 27
  • 47