简体   繁体   中英

Find depth of element with recursion using python

My task is to find depth of an element. I cannot change function depth in MAIN (this: depth('g', ['a', ['b', 'c', 'd'], ['e', 'f']]) ). Firs I want to find depth without recursion but I get wrong result. I tried with increment level but it returned 6 in this particular test case.

def depth(x, L):
    level = 0
    if not L:
        return 0;
    for i in range(len(L)):
        for j in L[i]:
            if x == j:
                return i
            else:
                continue
    
if __name__ == '__main__':
    depth('g', ['a', ['b', 'c', 'd'], ['e', 'f']])
    depth('d', ['a', ['b', 'c', 'd'], ['e', 'f']])

For these 2 cases result should be:

  1. Element g is not in the list
  2. Depth of an element d is 2

EDIT try with recursion:

def depth(x, L):
    level = 0
    if not L:
        return 0
    for i in range(len(L)):
        if x == L[i]:
            return i
        else:
            depth(x,L[i+1])

I'll focus on the recursive attempt, as it shows immediate problems:

...
for i in range(len(L)):
    if x == L[i]:
        return i
    else:
        depth(x,L[i+1])

First, when you do find the item, you return its position in the list. This has nothing to do with its depth in the nesting. For instance, if you search for b, c, d in three separate calls, your base case returns three different values (0, 1, 2) for them, even though they're at the same level. This guarantees a wrong answer.

Instead, you need to return 1 or 0 from your base case (depending on how you count the depth), and then simply add 1 at each level as you work back up the tree:

for i in range(len(L)):
    if x == L[i]:
        return 1   # ... or 0
    else:
        depth(x, ...) + 1

This will be more clear if you iterate through the elements, rather than the indices:

for item in L:
    if x == item:

Even more pressing is that when you do any recursion, you fail to return a value, so you'll get a result of None . Simply calling a function doesn't return the desired value. That last clause needs to be

    else:
        return depth(x, ...) + 1

Finally, when you recur, you must do so iff the item is a list:

for item in L:
    if isinstance(L, list):
        found = depth(x, item)
        if found is not None:
            return found + 1
    elif x == item:
        return 1
def depth_helper(find, nested_list):
    if find == nested_list:
        return 0
    else if type(find) == type([]) and find:
        return 1 + min((depth_helper(find, element) for element in find))
    else:
        return float('inf')

def depth(find, nested_list):
    result = depth_helper(find, nested_list)
    if result == float('inf'):
        print(f"Element {find} is not in the list")
    else:
        print(f"Depth of an element {find} is {result}")

We factor out the computation of the depth as a pure helper function.

I already said that i cannot change calling function

If you cannot change it, how are you expected to make it work? It's obvious by the two varying attempts of depth that you are able to change it to solve the problem. Anyway, I reordered my original answer so the outermost function name is depth -

def depth(x, L):
  def find(d, t):
    if isinstance(t, list):
      for v in t:
        yield from find(d + 1, v)
    else:
      yield (t, d)
  for (v, d) in find(0, L):
    if v == x:
      return d
print(depth('g', ['a', ['b', 'c', 'd'], ['e', 'f']]))
print(depth('d', ['a', ['b', 'c', 'd'], ['e', 'f']]))

Results -

None
2

Isolating concerns makes your code easier to read/write and promotes reuse within other areas of your program.

I think that this question comes from some kind of homework, my tips is trying to understand why something isn't working the way we want, go through the studying material again first and then ask for help to strangers

"Everybody should learn to program a computer, because it teaches you how to think.”

Anyway just some advice:

  1. the var level that you create and never use

  2. As pointed out by martin range starts from 0

  3. I don't understand the first if block, maybe you meant something like:

     if x not in L
  4. The recursion version has some core problems but I'll let you figure out by your self!

def depth(x, L):
    for i in range(len(L)):
        for j in L[i]:
            if x == j:
                return i + 1
    return "Not present"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM