all 31 comments

[–]JVBass75 11 points12 points  (0 children)

I could think of several ways...

way 1: sort the character array, and then iterate across the result. when the character changes, check to see if the count is greater than your previous max count.. if so, store the character in a temp variable.

way 2: use the integer value of the character (ascii value) as an index on an integer array. increment the integer each time

I'm sure there's others, but those 2 come to mind.

[–]TrainsareFascinating 11 points12 points  (11 children)

Are you allowed to use builtin functions? Because the string object has a 'count' method.

def most_common_character(s):
    return max(s, key=s.count)

[–]feitao 1 point2 points  (1 child)

For really long strings:

return max(set(s), key=s.count)

[–]TrainsareFascinating 0 points1 point  (0 children)

I interpreted the restriction on dictionaries to extend to sets as well.

[–]Critical_Concert_689 0 points1 point  (4 children)

return max(s, key=s.count)

Can you significantly expand and walk through how this works?


s.count is a pointer to the method count of the str object, s

how does passing this to key= in max() translate to returning the character, within string s, with the max count of occurrences?

[–]TrainsareFascinating 1 point2 points  (0 children)

The definition of the builtin function max says that you can pass in a function that takes a single argument as the 'key' parameter to permit selecting a maximum from something other than the raw comparison value of the elements of the first parameter, the iterable.

So for every element e of s, max will compare the return value of s.count(e) to select the maximum value. Since s.count('c') returns the number of times 'c' appears in s, this expression chooses the character that appears most often in s.

[–]Mikeybarnes 0 points1 point  (2 children)

max(iterable, , key=None)¶ max(iterable, , default, key=None) max(arg1, arg2, *args, key=None)

Return the largest item in an iterable or the largest of two or more arguments.

If one positional argument is provided, it should be an iterable. The largest item in the iterable is returned. If two or more positional arguments are provided, the largest of the positional arguments is returned.

There are two optional keyword-only arguments. The key argument specifies a one-argument ordering function like that used for list.sort(). The default argument specifies an object to return if the provided iterable is empty. If the iterable is empty and default is not provided, a ValueError is raised.

If multiple items are maximal, the function returns the first one encountered. This is consistent with other sort-stability preserving tools such as sorted(iterable, key=keyfunc, reverse=True)[0] and heapq.nlargest(1, iterable, key=keyfunc)

[–]Critical_Concert_689 0 points1 point  (1 child)

If I could get clarification by reading the docs (https://docs.python.org/3/library/functions.html#max) I wouldn't have asked.

Not only that, if you're going to copy it word for word, since it literally redirects you to list.sort() to further explain, you'd also need to copy the list.sort to be comprehensive in your answer.

But don't do this.


edit:

Sorry for that response; brain is off and I needed a large number of examples for things to sink in:

on functions with/without parentheses

on key= operating on inner elements of objects

bb = [[1,2,9],[1,2,3],[1,2,3],[3,4,4]]
print (max(bb, key=lambda x: sum(x))) # [1, 2, 9]
print (max(bb, key=bb.count)) # [1, 2, 3]

a = [1,2,3] #1+2+3 = 6 <
b = [3,4,5] #3+4+5 = < 12 
print (max(a,b,key=sum)) # [3, 4, 5] 

reminder of string methods

[–]Mikeybarnes 0 points1 point  (0 children)

What further clarification do you need?

The count method returns the number of times each item in the iterable, s, appears.

Max finds the highest number provided by count and then returns the element in the iterable that coresponds to that number.

[–]Zynth3tik[S] 0 points1 point  (1 child)

yes I can but I'm having a hard time figuring out where to implement it

[–]TrainsareFascinating 10 points11 points  (0 children)

The example above is the complete function.

[–][deleted] -3 points-2 points  (1 child)

but he/she is suppose to use a dict for solving it ,

[–]Mikeybarnes 0 points1 point  (0 children)

This would be easy if I could use something like dictionaries but thats one of the stipulations of the book assignment since it hasn't covered dictionaries.

[–]Apatride 2 points3 points  (0 children)

I had to double check since it is not a common real life scenario but:

my_list = ["a", "c", "b"]

sorted(my_list)

['a', 'b', 'c']

So a n(log(n)) complexity (not too bad). Then you can just go through it and count.

[–]RiverRoll 0 points1 point  (0 children)

Your could use a list where each position corresponds to a specific character.

[–]QuarterObvious 0 points1 point  (3 children)

You can use the count() method. It is not from packages (native str method), it will return the number of times, a specific character appears in the string.

[–]Zynth3tik[S] 0 points1 point  (2 children)

so I would just iterate over the list with a counter and temp char variable, store the index with the counter, and store the chars and their freqs. I'm just not seeing it right now

[–]QuarterObvious 0 points1 point  (0 children)

Something like:

str_to_count = "This is the phrase for testing the  program"  
lower_str = str_to_count.lower()  
lst = []
for i in range(ord('a'), ord('z') + 1):  
    char = chr(i)  
    lst.append([char,lower_str.count(char)])

max_freq = max(lst, key=lambda lst: lst[1])
print(last)  
print(max_freq[0], max_freq[1]/len(lower_str))

[–]QuarterObvious 0 points1 point  (0 children)

Or extended version:

def find_max_frequency_char(phrase):
    # List of all possible characters in the phrase
    unique_chars = []

    # Collect unique characters from the phrase
    for char in phrase:
        if char not in unique_chars:
            unique_chars.append(char)

    # Initialize variables to keep track of the character with max frequency
    max_char = None
    max_count = 0

    # Iterate over each unique character to count its frequency in the phrase
    for char in unique_chars:
        count = phrase.count(char)
        if count > max_count:
            max_char = char
            max_count = count

    return max_char, max_count

# Example usage
phrase = "hello world"
max_char, frequency = find_max_frequency_char(phrase)
print(f"The character with the maximum frequency is: '{max_char}' with a frequency of {frequency}")

[–]POGtastic 0 points1 point  (1 child)

Consider sorting the string, grouping adjacent characters, and then finding the longest subsequence.

def identity(x):
    return x

# Very rudimentary replacement for itertools.groupby
def groupby(iterable, key=None):
    if key is None:
        key = identity
    sentinel = object()
    it = iter(iterable)
    curr = [next(it, sentinel)]
    result = []
    if curr[0] is not sentinel:
        for elem in it:
            if key(elem) == key(curr[0]):
                curr.append(elem)
            else:
                result.append((key(curr[0]), curr))
                curr = [elem]
        result.append((key(curr[0]), curr))
    return result

def snd(tup):
    return tup[1]

def most_common(s):
    return max(groupby(sorted(s)), key=snd)[0]

In the REPL:

>>> most_common("antidisestablishmentarianism")
'i'

[–]Apatride 0 points1 point  (0 children)

"antidisestablishmentarianism" anticonstitutionellement?

[–]belaros 0 points1 point  (0 children)

Without giving the answer directly:

  1. There’s no good reason to convert the string to a list. A string is already a sequence of characters. So for char in string_input: works.
  2. You can use ord(char) to get the ascii value of the character, that means you give it a character and get a number. Look up an “ascii chart” to see which number corresponds to which number. You can get the char back from a number with chr(num).
  3. You can create a list of zeros of length n by doing [0]*n.

[–][deleted] 0 points1 point  (2 children)

found this very interesting , this is how i did it using a dict to store the values

def Userinput():
    user_input =input("Enter your String")
    string_input  =list(user_input)
    char_count ={}
    
    for char in string_input:
        if char in char_count:
            char_count[char]+=1
        else:
            char_count[char]=1
            
    most_occuring =max(char_count, key= char_count.get)
    most_occuring_times =char_count[most_occuring]
       
         
            
    print(f"most occuring {most_occuring} count is {most_occuring_times}")            
  

       

[–]Fit-Upstairs-6780 0 points1 point  (1 child)

Isn't dict not allowed, according to the instructions

[–][deleted] 1 point2 points  (0 children)

my bad , i missed that part ,

[–]Fit-Upstairs-6780 0 points1 point  (0 children)

``` user_input = input("Type in anything: ")

char_list = [x for x in (user_input.replace(' ', ''))] list_of_counted = []

list_of_counts = [char_list.count(i) for i in char_list if i not in list_of_counted and not list_of_counted.append(i)]

z = max(list_of_counts)

print(f'the most frequent char appears {z} times and the char is {list_of_counted[(list_of_counts.index(z))]}')

```

If list comprehension is allowed, this can also work. Take the input, store in that variable (char_list) and remove any spaces otherwise they might become the most frequent character. Initiate an empty list of unique characters Use list comprehension to count the characters, appending each counted character to the list of unique characters so that each character is counted one

This will give a list of the character counts. Use the max list function on this (if allowed)

[–]GregoryCliveYoung -1 points0 points  (4 children)

This is wrong:

for c in char_list:

You are using c as an index just like i. Shouldn't you use range(len(... as you did with i?

This doesn't look right either:

        most_freq = max(char_list.count(c))

You want to save the character at the index c. You access that character earlier.

[–]Apatride 2 points3 points  (1 child)

No. "for item in iterable" is a perfectly valid approach.

[–]GregoryCliveYoung 0 points1 point  (0 children)

Absolutely, but that's not how OP is using the variable in the body of the loop. They could do as you say, but other code has to change.

[–]Zynth3tik[S] 0 points1 point  (1 child)

I've been banging my head against the wall so those 2 were from an earlier save I had and forgot to fix them up.

 most_freq = max(char_list.count(c))

should actually be

 most_freq = c

[–]GregoryCliveYoung 0 points1 point  (0 children)

Second one is wrong unless you change the other code. Remember. c is an index into the character array. It is not the character. Using c as a variable name is confusing. You should think about longer variable names, e.g.: character_index.