Reputation: 137
I have a list of dictionary like below:
targer = [
{"id":1,"search":"xyz"},
{"id":2,"children":[
{"id":3,"search":'xyz'},
{"id":4,"search":'xyz'},
{"id":5,"children":[
{"id":6,"search":'xyz'},
{"id":7,"search":'xyz'},
{"id":8,"search":'xyz'}]},
{"id":9,"search":'xyz'},
{"id":10,"search":'xyz'}]},
{"id":11},{"id":12}]
Now i want to make a list of dictionary like below from target list:
output = [
{'tier1': 1, 'searchterm': 'xyz'},
{'tier1': 2, 'tier2': 3,'searchterm': 'xyz'},
{'tier1': 2,'tier2': 4,'searchterm': 'xyz'},
{'tier1': 2, 'tier2': 5,'tier3': 6,'searchterm': 'xyz'},
{'tier1': 2, 'tier2': 5,'tier3': 7,'searchterm': 'xyz'},
{'tier1': 2, 'tier2': 5,'tier3': 8, 'searchterm': 'xyz'},
{'tier1': 2, 'tier2': 9,'searchterm': 'xyz'},
{'tier1': 2, 'tier2': 10,'searchterm': 'xyz'},
{'tier1': 11, 'searchterm': 'xyz'},
{'tier1': 12, 'searchterm': 'xyz'}]
I tried some steps: 1.first i convert target list in to list like below:
mylist = [
[1, 'xyz'],
[2, 3, 'xyz'],
[2, 4, 'xyz'],
[2, 5, 6, 'xyz'],
[2, 5, 7, 'xyz'],
[2, 5, 8, 'xyz'],
[2, 9, 'xyz'],
[2, 10, 'xyz'],
[11],
[12]]
2.then i applied below code on mylist to get output:
for i in lis:
dic={}
length=len(i)
if length==2:
dic['tier1']=i[0]
dic['searchterm']=i[1]
if length==3:
dic['tier1']=i[0]
dic['tier2']=i[1]
dic['searchterm']=i[2]
if length==4:
dic['tier1']=i[0]
dic['tier2']=i[1]
dic['tier3']=i[2]
dic['searchterm']=i[3]
if length==5:
dic['tier1']=i[0]
dic['tier2']=i[1]
dic['tier3']=i[2]
dic['tier4']=i[3]
dic['searchterm']=i[4]
if length==6:
dic['tier1']=i[0]
dic['tier2']=i[1]
dic['tier3']=i[2]
dic['tier4']=i[3]
dic['tier5']=i[4]
dic['searchterm']=i[5]
target.append(dic)
But i want to output from direct target list with out applying above steps. Please help to solve this problem.
Upvotes: 0
Views: 103
Reputation: 11543
recursive generator will do the trick:
def flatten(list_of_dicts, tier = 1, prev = {}):
for item in list_of_dicts:
curr = prev.copy()
curr['tier%d' %tier] = item['id']
if 'children' in item:
for next in flatten(item['children'], tier + 1, curr):
yield next
else:
if 'search' in item: #some items don't have it
curr['searchterm'] = item['search']
yield curr
>>> list(flatten(targer))
[{'tier1': 1, 'searchterm': 'xyz'}, {'tier1': 2, 'searchterm': 'xyz', 'tier2': 3}, {'tier1': 2, 'searchterm': 'xyz', 'tier2': 4}, {'tier1': 2, 'searchterm': 'xyz', 'tier3': 6, 'tier2': 5}, {'tier1': 2, 'searchterm': 'xyz', 'tier3': 7, 'tier2': 5}, {'tier1': 2, 'searchterm': 'xyz', 'tier3': 8, 'tier2': 5}, {'tier1': 2, 'searchterm': 'xyz', 'tier2': 9}, {'tier1': 2, 'searchterm': 'xyz', 'tier2': 10}, {'tier1': 11}, {'tier1': 12}]
Upvotes: 1