Jeison AK
Jeison AK

Reputation: 23

Loops and Dictionary

How to loop in a list while using dictionaries and return the value that repeats the most, and if the values are repeated the same amount return that which is greater? Here some context with code unfinished

def most_frequent(lst):
        dict = {}
        count, itm = 0, ''
        for item in lst:
            dict[item] = dict.get(item, 0) + 1
            if dict[item] >= count:
                count, itm = dict[item], item
        return itm
    
    #lst = ["a","b","b","c","a","c"]
    lst = [2, 3, 2, 2, 1, 3, 3,1,1,1,1] #this should return 1
    lst2 = [2, 3, 2, 2, 1, 3, 3] # should return 3
    print(most_frequent(lst))

Upvotes: 0

Views: 111

Answers (3)

Tuan Le PN
Tuan Le PN

Reputation: 384

I reuse your idea which is quite neat, and I just modified your program a bit.

def get_most_frequent(lst):
    counts = dict()
    most_frequent = (None, 0) # (item, count)

    ITEM_IDX = 0
    COUNT_IDX = 1

    for item in lst:
        counts[item] = counts.get(item, 0) + 1
        if most_frequent[ITEM_IDX] is None:
            # first loop, most_frequent is "None"
            most_frequent = (item, counts[item])
        elif counts[item] > most_frequent[COUNT_IDX]:
            # if current item's "counter" is bigger than the most_frequent's counter
            most_frequent = (item, counts[item])
        elif counts[item] == most_frequent[COUNT_IDX] and item > most_frequent[ITEM_IDX]:
            # if the current item's "counter" is the same as the most_frequent's counter
            most_frequent = (item, counts[item])
        else:
            pass # do nothing
    return most_frequent

lst1 = [2, 3, 2, 2, 1, 3, 3,1,1,1,1, 2] # 1: 5 times
lst2 = [2, 3, 1, 3, 3, 2, 2] # 3: 3 times
lst3 = [1]
lst4 = []
print(get_most_frequent(lst1))
print(get_most_frequent(lst2))
print(get_most_frequent(lst3))
print(get_most_frequent(lst4))

Upvotes: 1

RustyB
RustyB

Reputation: 147

Your code produces the result as you describe in your question, i.e. 1. However, your question states that you want to consider the case where two list elements are co-equals in maximum occurrence and return the largest. Therefore, tracking and returning a single element doesn't satisfy this requirement. You need to compile the dict and then evaluate the result.

def most_frequent(lst):
    dict = {}
    for item in lst:
        dict[item] = dict.get(item, 0) + 1

    itm = sorted(dict.items(), key = lambda kv:(-kv[1], -kv[0]))
    return itm[0]

#lst = ["a","b","b","c","a","c"]
lst = [2, 3, 2, 2, 2, 2, 1, 3, 3,1,1,1,1] #this should return 1
lst2 = [2, 3, 2, 2, 1, 3, 3] # should return 3
print(most_frequent(lst))

I edited the list 'lst' so that '1' and '2' both occur 5 times. The result returned is a tuple: (2,5)

Upvotes: 1

felipe
felipe

Reputation: 8055

Here is a different way to go about it:

def most_frequent(lst):

    # Simple check to ensure lst has something.
    if not lst:
        return -1

    # Organize your data as: {number: count, ...}
    dct = {}
    for i in lst:
        dct[i] = dct[i] + 1 if i in dct else 1

    # Iterate through your data and create a list of all large elements.
    large_list, large_count = [], 0
    for num, count in dct.items():
        if count > large_count:
            large_count = count
            large_list = [num]
        elif count == large_count:
            large_list.append(num)

    # Return the largest element in the large_list list.
    return max(large_list)

There are many other ways to solve this problem, including using filter and other built-ins, but this is intended to give you a working solution so that you can start thinking on how to possibly optimize it better.

Things to take out of this; always think:

  • How can I break this problem down into smaller parts?
  • How can I organize my data so that it is more useful and easier to manipulate?
  • What shortcuts can I use along the way to make this function easier/better/faster?

Upvotes: 1

Related Questions