0

I get the following tuple :(12, (6, (2,), (8,)), (15, (14,), (18,))) and I need to return an instance of Tree in the Following form : Tree(12, Tree(6, Tree(2), Tree(8)), Tree(15, Tree(14), Tree(18)))

My class is :

class Tree():
    def __init__(self, entry, left=None, right=None):
        self.entry = entry
        self.left = left
        self.right = right
    def __repr__(self):
        if not self.left and not self.right:
            return "Tree({0})".format(repr(self.entry))
        return "Tree({0},{1},{2})".format(repr(self.entry),repr(self.left),repr(self.right))

The problem that I can not understand is why it does not enter to the base condition? And how can I fix the function.

The function I did is:

def build_tree(tree):
    if type(tree) != tuple:
        return Tree(tree)
    return Tree(tree[0], build_tree(tree[1]), build_tree(tree[2]))

The activation is :

tree1 = (12, (6, (2,), (8,)), (15, (14,), (18,)))
t1=build_tree(tree1)
print(t1)
  • Please clarify what you mean by "I get a tuple that is built from 3 elements and I need to return an instance of Tree in the Following form : Tree(12, Tree(6, Tree(2), Tree(8)), Tree(15, Tree(14), Tree(18)))" As written, this question doesn't make sense. – itprorh66 Jan 08 '22 at 15:53
  • I'll fix it, thanks. – Michael ilkanayev Jan 08 '22 at 16:06

3 Answers3

2

As the innermost tuples just have one member, avoid using an index that is out of range and just slice out whatever there is as tuple members after the node value, and map those to your function.

So replace the last return statement in your build_tree function with this:

return Tree(tree[0], *map(build_tree, tree[1:]))
trincot
  • 317,000
  • 35
  • 244
  • 286
0

The problem is tree[1] and tree[2] are sometimes unset for entries like (2,) or (8,). This will result in an IndexError. A workaround is to "pad" the tuple with (None, None) values and then trim down to 3 elements -

def build_tree(a):
  if a:
    (entry, left, right) = (a + (None, None))[:3]
    return Tree(entry, build_tree(left), build_tree(right))
  else:
    return None
x = (12, (6, (2,), (8,)), (15, (14,), (18,)))
mytree = build_tree(x)
print(mytree)
Tree(12,Tree(6,Tree(2),Tree(8)),Tree(15,Tree(14),Tree(18)))

I will remark a functional approach with a thin class wrapper will make it easier for you to grow the functionality of your tree. For more information on this technique, see this related Q&A.

Mulan
  • 129,518
  • 31
  • 228
  • 259
-1

You want isinstance

def build_tree(tree):
    if isinstance(tree, tuple):
        if len(tree) == 1:
            return Tree(tree[0])
        return Tree(tree[0], build_tree(tree[1]), build_tree(tree[2]))
    return Tree(tree)
print(build_tree((12, (6, 2, 8), (15, 14, 18))))
Helios
  • 675
  • 4
  • 13
  • This doesn't work for the user's homogenous input of `(12, (6, (2,), (8,)), (15, (14,), (18,)))` – Mulan Jan 08 '22 at 16:18
  • Thanks for the help, still this function does not work for me . This causes the following error: tuple index out of range – Michael ilkanayev Jan 08 '22 at 16:21
  • you added this example post my answer, if all the feeds are tuples then you dont need to check for tuple type at all, just length. I have updated – Helios Jan 08 '22 at 17:48