Reputation:
dic = {}
count = 0
i = 0
str_in = str_in.replace(' ','')
while i < len(str_in):
count = str_in.count(str_in[i])
dic[str_in[i]] = count
i += 1
for key in dic:
if key == max(dic, key=dic.get):
return key
break
The dictionary that is made in this program is
{'i': 1, 'h': 2, 'j': 2, 'o': 2, 'n': 1, 's': 2}
from the input 'joshin josh'
I am pretty sure the dictionary's max value returns h because it is the first value in the dictionary with the highest value, even if tied. I want it to return j because that is the first letter I put into the dictionary. It seems like the dictionary automatically sorts the letters alphabetically, which I also don't understand. I want this to work with any string and all tied letters, not just this particular string. Correct me if I am wrong on anything, I am a noob.
Upvotes: 1
Views: 1007
Reputation: 21609
Another approach, by using OrderedDict
as a mixin class it allows an ordered Counter
class to be easily composed. You can then use the first entry of the list returned from the most_common
method.
e.g.
from collections import Counter, OrderedDict
class OrderedCounter(Counter, OrderedDict):
pass
oc = OrderedCounter('joshin josh')
print(oc.most_common()[0])
Will give you back a tuple of the letter and the number of occurrences. e.g.
('j', 2)
You'd need to protect the [0]
in the case where you were passing an empty string, Where nothing is most common.
To better understand why this works I recommend watching Raymond Hettingers Super Considered Super talk from PyCon 2015. Youtube link here
Upvotes: 2
Reputation: 8610
If you don't want to manually count, you could use Python's Counter
to count letter occurrences, find the max, then return the first letter in your string that matches that count:
from collections import Counter
string = 'joshin josh'
counts = Counter(string)
max_count = max(counts.values())
print(next(c for c in string if counts[c] == max_count)) # j
next(c for c in string if letter_counts[c] == max_count)
returns the first letter in the given string for which the count is the max count.
A more optimal approach:
The previous approach would have you traverse the string in the worst case three times. For a one-pass approach, it would be most efficient to just keep track of the max count and letter corresponding to it as you iterate through the string:
from collections import defaultdict
counts = defaultdict(int)
max_letter = None
max_count = 0
string = 'joshin josh'
for c in string:
counts[c] += 1
if counts[c] > max_count:
max_letter = c
max_count = counts[c]
print(max_letter) # j
Upvotes: 1
Reputation: 59274
You can use an OrderedDict
Just a simple change would resolve your problem
ord_dic = OrderedDict(sorted(dic.items(), key=lambda t: str_in.index(t[0])))
So you could use something like
dic = {}
count = 0
i = 0
str_in = str_in.replace(' ','')
while i < len(str_in):
count = str_in.count(str_in[i])
dic[str_in[i]] = count
i += 1
ord_dic = OrderedDict(sorted(dic.items(), key=lambda t: str_in.index(t[0])))
for key in ord_dic:
if key == max(ord_dic, key=ord_dic.get):
return key
break
Do not forget to import OrderedDict
Add this line at the top of your code:
from collections import OrderedDict
Upvotes: 0