zombine
zombine

Reputation: 19

Python - Find the "depth" of an element in list in a recursive loop

I want to know the depth of an element in a list in Python using a recursive loop (not a function) but it doesn't work. I find some answers with functions but it's not the point here.

Something like 'a' is depth 2 and 'd' is depth 3 in the list below

Here is my code:

list1 = [['x','y'], ['z','p'], ['m',['a','b','c',['d','e']]]]

level = 0

def print_list(l):
    for e in l:
        global level
        if type(e) == list:
            print_list(e)
            level +=1
        else:
           print(str(e) + ",", str(level))

print_list(list1)

Result:

x, 0
y, 0
z, 1
p, 1
m, 2
a, 2
b, 2
c, 2
d, 2
e, 2

Someone has an idea?

Upvotes: 1

Views: 1649

Answers (4)

Mark Tolonen
Mark Tolonen

Reputation: 177481

Generators are the way to go so you don't hard-code how the elements are used or displayed.

The following also uses an internally-defined function so the user can't accidentally pass an extra parameter that messes up level:

list1 = ['a',['b',['c',['d'],'e'],'f'],'g']

def enum_list(l):
    def _enum_list(l,level=1):
        for e in l:
            if isinstance(e,list):
                yield from _enum_list(e,level+1)
            else:
               yield e,level
    yield from _enum_list(l)

for item,level in enum_list(list1):
    print(f'{item}, {level}')

Output:

a, 1
b, 2
c, 3
d, 4
e, 3
f, 2
g, 1

Upvotes: 0

Mark
Mark

Reputation: 92440

Using generators is really convenient for this kind of task. It allows you to produce values on demand or as a list and makes the logic very clear. I'm starting the depth at -1 because I want the first nested elements to be at depth 1 (level zero would be immediate nested values like a in ['a', ['b',...]]:

list1 = [['x','y'], ['z','p'], ['m',['a','b','c',['d', 'e']]]]

def levels(l, depth = -1):
    if not isinstance(l, list):
        yield (l, depth)
    else:
        for sublist in l:
            yield from levels(sublist, depth + 1)

list(levels(list1))

result:

[('x', 1),
 ('y', 1),
 ('z', 1),
 ('p', 1),
 ('m', 1),
 ('a', 2),
 ('b', 2),
 ('c', 2),
 ('d', 3),
 ('e', 3)]

It would be just as easy to make this a dictionary or use various itertools to manipulate it.

Upvotes: 2

גלעד ברקן
גלעד ברקן

Reputation: 23955

Change these two lines:

print_list(e)
level +=1

to

level += 1
print_list(e)
level -= 1

Upvotes: 1

chluebi
chluebi

Reputation: 1829

In general I reccomend not using global variables, especially in recursion.

list1 = [['x','y'], ['z','p'], ['m',['a','b','c',['d','e']]]]

def print_list(li, level):
    for e in li:
        if type(e) == list:
            level += 1
            print_list(e, level)
        else:
           print(str(e) + ",", str(level))

print_list(list1, 0)

Output:

x, 1
y, 1
z, 2
p, 2
m, 3
a, 4
b, 4
c, 4
d, 5
e, 5

Upvotes: 1

Related Questions