Tristan Salord
Tristan Salord

Reputation: 67

Extract string in nested lists by level

Ok so it's a recursive break minded thing. I have irregular nested list that looks like that: proxy=['a','b',['c','d','e'],'f',['g',['h','j'],'k'],'l']

I want to extract, thanks a recursive function, items by level. The idea is to have an output like: level 1 : a,b,f,l level 2: c,d,e,g,k level3 : h,j These nested list represents n-ary tree. So far i tried sthg like that:

def extractbylevel(chain):
    r=[]
    depth=0
    for item in chain:
        if isinstance(item,str):
            r.append((depth,item))
            if depth > 0:
                depth -=1
        else:
            depth += 1
            r = r+extractbylevel(item)
    return r

result output is:

[(0, 'a'),
 (0, 'b'),
 (0, 'c'),
 (0, 'd'),
 (0, 'e'),
 (1, 'f'),
 (0, 'g'),
 (0, 'h'),
 (0, 'j'),
 (1, 'k'),
 (1, 'l')]

So problem is the depth level...

Recursivity is going to blow up my minde... ^^ Thanks a lot for your help!!!!

Upvotes: 1

Views: 274

Answers (3)

ThunderPhoenix
ThunderPhoenix

Reputation: 1883

Try this code:

def f(l, d=0):
r = []
for e in l:
    if type(e) == str:
        r.append((e, d))
    else:
        r += f(e, d+1)
return r

You call the function like this:

L = ['a', 'b', ['c', 'd', 'e'], 'f', ['g', ['h', 'j'], 'k'], 'l']
f(L, 0)  # or just like f(L)

Upvotes: 0

Balaji Ambresh
Balaji Ambresh

Reputation: 5012

Here you go:

In [1]: %paste                                                                  
from collections import defaultdict

def extractbylevel(chain, depth, levels):
    for item in chain:
        if isinstance(item,str):
            levels['level {}'.format(depth)].append(item)
        else:
            extractbylevel(item, depth + 1, levels)

proxy=['a','b',['c','d','e'],'f',['g',['h','j'],'k'],'l']
output = defaultdict(list)
extractbylevel(proxy, 1, output)

for k, v in output.items():
    print(k, v)

## -- End pasted text --
level 1 ['a', 'b', 'f', 'l']
level 2 ['c', 'd', 'e', 'g', 'k']
level 3 ['h', 'j']

Upvotes: 0

Subhrajyoti Das
Subhrajyoti Das

Reputation: 2710

I have edited your code to work. The trick is not maintaining a local variable depth but to pass the depth to the function instance using it. Below is the code:

chain = ['a','b',['c','d','e'],'f',['g',['h','j'],'k'],'l']

def extractbylevel(chain, depth=0):
    r=[]
    for item in chain:
        if isinstance(item,str):
            r.append((depth,item))
        else:
            r = r+extractbylevel(item, depth+1)
    return r
    
print(extractbylevel(chain))

#answer
[(0, 'a'), (0, 'b'), (1, 'c'), (1, 'd'), (1, 'e'), (0, 'f'), (1, 'g'), (2, 'h'), (2, 'j'), (1, 'k'), (0, 'l')]

Upvotes: 2

Related Questions