Home > Back-end >  How can optimize below code for counting repeat of each elements in nested of nested list
How can optimize below code for counting repeat of each elements in nested of nested list

Time:07-16

The code I wrote counts the frequency of each element in a nested list. I have a lot of repeated code. How can I optimize it? I don't want to use built-in function or lib.

Input:

items = [10, "ninety nine", [99, 250, [90, "fifty"], 4.5, [50, 80], 90, "ninety nine"], ["fifty"]]

Output:

{10: 1, 'ninety nine': 2, 99: 1, 250: 1, 90: 2, 'fifty': 2, 4.5: 1, 50: 1, 80: 1}

Code:

items = [10, "ninety nine", [99, 250, [90, "fifty"], 4.5, [50, 80], 90, "ninety nine"], ["fifty"]]

dict1 = dict()


for i in items:
    if isinstance(i, list):
        for j in i:
            if isinstance(j, list):
                for k in j:
                    if k not in dict1:
                        dict1[k] = 1
                    else:
                        dict1[k]  = 1
            else:
                if j in dict1:
                    dict1[j]  = 1
                else:
                    dict1[j] = 1

    else:
        if i in dict1:
            dict1[i]  = 1
        else:
            dict1[i] = 1


print(dict1)

Any suggestions would be greatly appreciated.

CodePudding user response:

You can use recursion to flatten the list and then count specific items:

items = [
    10,
    "ninety nine",
    [99, 250, [90, "fifty"], 4.5, [50, 80], 90, "ninety nine"],
    ["fifty"],
]


def get_items(v):
    if isinstance(v, list):
        for i in v:
            yield from get_items(i)
    else:
        yield v


cnt = {}
for i in get_items(items):
    cnt[i] = cnt.get(i, 0)   1

print(cnt)

Prints:

{
    10: 1,
    "ninety nine": 2,
    99: 1,
    250: 1,
    90: 2,
    "fifty": 2,
    4.5: 1,
    50: 1,
    80: 1,
}

CodePudding user response:

You can write a recursive function to flatten your nested list then use Collection.Counter to get the count of each element.

from collections import Counter

items = [10, "ninety nine", [99, 250, [90, "fifty"], 4.5, [50, 80], 
                             90, "ninety nine"], ["fifty"]]

def flatten_list(items, lst):
    for item in items:
        if isinstance(item , list):
            flatten_list(item, lst)
        else:
            lst  = [item]
    return lst

res = flatten_list(items, [])
print(dict(Counter(res)))

{10: 1, 'ninety nine': 2, 99: 1, 250: 1, 90: 2, 'fifty': 2, 4.5: 1, 50: 1, 80: 1}
  • Related