-1

In the following code, I understand that the print of tree(named in the code) and parent(named in the code) should not be the same. But I do not understand, why the tree is always updating according to the updating of parent? (This question continues the last question here)

Code:

class node(object):
    def __init__(self, value):
        self.value = value
        self.children = []
    def __repr__(self, level=0):
        ret = "\t"*level+repr(self.value)+"\n"
        for child in self.children:
            ret += child.__repr__(level+1)
        return ret
    def add(self, nod):
        self.children.append(nod)
list_0 = ['AA', 'BB', 'CC', 'DD']
tree = parent = node(list_0[0])
i=1
while i<len(list_0):
    current_node = node(list_0[i])
    parent.add(current_node)
    parent = current_node
    i+=1
print(tree)
print(parent)

Output:

'AA'
    'BB'
        'CC'
            'DD'

'DD'

In the code, it is obvious that the parent is re-initialized every time in the loop, but according to my understanding, while the parent is updating, the tree should not be updated accordingly. Because once the parent is re-initialized in the loop, it then does not have the same id(maybe address) with the tree anymore, then the tree will not be changed according to the parent.

Question:

  1. why the tree is still updating according to the parent even the id(parent) is changed every time in the loop?

  2. how the tree is linking to the parent which is inside the loop? e.g., node[1], node[2].(update)

Appreciate any comment or explanation, thanks in advance!

Melina
  • 293
  • 3
  • 11
  • 1
    The new `parent` is still a child of the previous `parent` so adding children to it adds "grandchildren" to the previous one. Hence, the original tree keeps growing. – user2390182 May 07 '21 at 09:52
  • Thanks @schwobaseggl, if it is as you've mentioned, i.e., 'the `parent` in the loop is a `child` of `parent` outside the loop', why the `print(parent)` (the last line) does not have the same result with the `print(tree)`? The `parent` in the last is the 'original `parent`' (above the loop) or the `child/grandchild`? Thanks! – Melina May 07 '21 at 09:56
  • A loop does not open a new scope (or namespace) in python. The `parent` binding after the loop is the one from the loop's last iteration. – user2390182 May 07 '21 at 10:56

1 Answers1

1

I think its because your tree is always pointing to the root node, but parent is pointing to the next node.

Let's define some nomenclature:

  • node[0]: First node created
  • node[1]: Second node created
  • ref(node[X]): Reference to the node X
  • ref(node[0]) -> ref(node[1]): Reference to node 0 that has as children the node 1

Step 0

tree = parent = node(list_0[0])

tree is pointing to ref(node[0])

parent is pointing to ref(node[0])

Step 1 (inside the while loop)

parent = current_node

tree still pointing to ref(node[0]) -> ref(node[1])

parent is pointing to ref(node[1])

Step n

tree still pointing to ref(node[0]) -> ref(node[1]) -> .... -> ref(node[n])

parent is pointing to ref(node[n])

A more graphic way to explain this:

# Step 0
tree, parent  ->  node[0]

# Step 1
tree   ->         node[0]
                    |
parent ->         node[1]

# Step 2
tree   ->         node[0]
                    |
                  node[1]
                    |
parent ->         node[2]

# Step n
tree   ->         node[0]
                    |
                  node[1]
                    |
                   ...
                    |
parent ->         node[n]

A node is being added as child of another node in this line:

parent.add(current_node)

So tree is always pointing to the root element of the tree and parent is pointing to the last element of the tree. That's the reason why the ids are different!

I hope I have provided you with useful information!

AlbertFX91
  • 108
  • 7
  • Thanks@AlbertFX91, this is very clear. One more question: in the 'step 1', how does `tree still pointing to ref(node[0]) -> ref(node[1])` is implemented? why does the `ref(node[0])` can referenced to the `ref(node[1])`? – Melina May 07 '21 at 10:09
  • You're welcome! at the step 0 the node[0] is created without child. And the node[0] is assigned to the variables tree and parent. In the next step, a new node is added to the previous one, so node[0] has a new child node[1]. Tree still pointing to node[0] but parent is pointing to node[1]! – AlbertFX91 May 07 '21 at 10:15
  • I've modified the answer by adding a more graphic way to explain it! – AlbertFX91 May 07 '21 at 10:21
  • 1
    Hi thanks, I see it now, I was wondering at your 'step 1', how the `tree`(node[0]) is linked to the `node[1]`. Now I see that it is because the `parent.add(current_node)`, at this moment, the `parent` is not a new `node` (node[1]) yet. It points to the new `node` (node[1]) after the `parent = current_node`. Many thanks:) – Melina May 07 '21 at 10:27