Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access (and modify) arbitrary items in a hierarchy of classes in python

Tags:

python

I have a class built in a way as follows for building a tree structure.

class Node(object):
    def __init__(self, data):
        self.data = data
        self.children = []

    def add_child(self, obj):
        self.children.append(obj)


n00 = Node('n00')
n00.add_child(Node('n000'))
n00.add_child(Node('n001'))

n0 = Node('n0')
n0.add_child(n00)
n0.add_child(Node('n01'))
n0.add_child(Node('n02'))

n1 = Node('n1')
n1.add_child(Node('n10'))
n1.add_child(Node('n11'))

n20 = Node('n20')
n20.add_child(Node('n200'))
n20.add_child(Node('n201'))

n2 = Node('n2')
n2.add_child(n20)
n2.add_child(Node('n21'))

h = Node('head')
h.add_child(n00)
h.add_child(n01)
h.add_child(n02)

Now that when I want to only access an item, it can be done by with a simple function such as:

def access(tree, *id):
    item = tree
    for i in id:
        item = item.children[i]

    return item.data

print(access(h,0,1))

The problem is when I want to make changes to any node, I cannot use this method and always need to manually type in the lengthy members such as:

h.children[1].children[0].data = 'new value'

or

h.children[0].children[0].children[1].add_child(Node('n0010'))

Now whenever the depth of the tree gets deeper, it becomes quite painful to repeatedly type all this. Is there a 'Python' way to make changes to items in a tree similar to the access method?

like image 243
Ghostx Avatar asked Dec 01 '25 13:12

Ghostx


1 Answers

Just go ahead and modify the node: Use the same "walking" technique as in your access method, only then don't return item.data but assign a new value to it:

def modify(new_data, tree, *id):
    item = tree
    for i in id:
        item = item.children[i]

    item.data = new_data

Example:

print(access(h, 0, 1))
modify("n001new", h, 0, 1)
print(access(h, 0, 1))

Which prints:

n001
n001new

Same thing for adding children:

def insert_child(new_child, tree, *id):
    item = tree
    for i in id:
        item = item.children[i]

    item.add_child(new_child)

Call it like:

insert_child(Node('n0010'), h, 0, 1)
like image 138
finefoot Avatar answered Dec 04 '25 02:12

finefoot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!