# Python Recursive Tree

## Question:

I’m new to programming and I want to define a function that allows me to find an element in a non-binary tree, and keep track of all the parentals of that element on a list.

The tree is coded as a tuple, where index 0 is the parent, and index 1 is a list of its childrens. The list contains a tuple for each children that is composed the same way as before(index 0 is the parent, and index 1 is the children).

Example:

```
tree_data = (
'Alan', [
(
'Bob', [
('Chris', []),
(
'Debbie', [
('Cindy', [])
]
)
]
),
(
'Eric', [
('Dan', []),
(
'Fanny', [
('George', [])
]
)
]
),
('Hannah', [])
]
)
```

Looking for ‘George’ would return the following: `['George', 'Eric'. 'Alan']`

So far i have the following: I have managed to only append the element and the direct parent, but not any further.

Also if i add a return statement to the function, the result come as None. Would appreciate a little help.

```
lst = []
def list_parentals(tree, element):
if tree[0] == element:
lst.append(element)
else:
for child in tree[1]:
list_parentals(child, element)
if child[0] == element:
lst.append(tree[0])
```

## Answers:

Instead of externally keeping a list you can build it as you go.

```
def list_parentals(tree, element, parents):
this, children = tree
new_parents = [this] + parents
if this == element:
return new_parents
else:
for child in children:
x = list_parentals(child, element, new_parents)
# If x is not None, return it
if x:
return x
list_parentals(t, 'George', [])
# ['George', 'Fanny', 'Eric', 'Alan']
```

For "my recursive function returns None", that is a very, very classical problem. You’ll find hundred of detailed answers about that on SO searching these words.

But in short, a recursive function must return something always, not just when it found something. Typically, on such an example, you must return a result when you found the correct leaf. But if you don’t want that result to be lost, then, you must also return something when you call that recursion that found the leaf. And when you call that recursion that called that recursion that found the leaf.

Keep in mind that what you get as a final result is the return value of the first call to `list_parentals`

. If that first call doesn’t return anything, then, it doesn’t matter that some recursive subcalls did.

Secondly, the way to build such a path is precisely to take advantage of the recursion. Trying to create a list in a global variable when you find a matching leaf is not easy. And you may end up trying to compute that with a iterative algorithm, when the whole point of recursion is to do that for you.

Here is a working recursive method (I tried to keep it as close are your own code as possible)

```
tree=('Alan', [('Bob', [('Chris', []), ('Debbie', [('Cindy', [])])]), ('Eric', [('Dan', []), ('Fanny', [('George', [])])]), ('Hannah', [])])
def list_parentals(tree, element):
if tree[0] == element:
return [element]
else:
for child in tree[1]:
sub=list_parentals(child, element)
if sub:
return [tree[0]] + sub
return []
r=list_parentals(tree, 'George')
print(f"{r=}")
```

The logic of that is that `list_parental(tree, 'George')`

returns the path in tree to leaf ‘George’, or `[]`

(or None, or False, doesn’t matter) if no such leaf is found.

So (just think of it as a mathematical expression, not as code, for now), `list_parental(('Alan', [('Bob', [('Chris', []), ('Debbie', [('Cindy', [])])]), ('Eric', [('Dan', []), ('Fanny', [('George', [])])]), ('Hannah', [])]), 'George')`

is just `Alan`

plus `list_parental((‘Eric’, [(‘Dan’, []), (‘Fanny’, [(‘George’, [])])]), ‘George’).

“list_parental((‘Eric’, [(‘Dan’, []), (‘Fanny’, [(‘George’, [])])]), ‘George’)`is just`

Eric`plus`

list_parental((‘Fanny’, [(‘George’, [])]), ‘George’)`.

`list_parental(('Fanny', [('George', [])]), 'George')`

is just `Fanny`

plus `list_parental(('George', []), 'George')`

.

`list_parental(('George', []), 'George')`

is just `George`

.

To keep this consistent, all returns must be lists.

Hence my code.

`list_parental(tree, leafName)`

is `[leafName]`

is the root of the tree match `leafName`

.

Else

`list_parental(tree, leafName)`

is `[tree[0]] + list_parental(child, leafName)`

if one of the child contains leafName, that is if `list_parental(child, leafName)`

is not empty.