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}