user6815110
user6815110

Reputation:

How to return the first highest value that is placed in a dictionary

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

Answers (3)

Paul Rooney
Paul Rooney

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

Karin
Karin

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

rafaelc
rafaelc

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

Related Questions