0

I have the following class:

class Node:

def __init__(self, id, parent):
    self.id = id
    self.parent = parent

Some objects of the node class:

n0 = Node(0, None)
n1 = Node(1, n0)
n2 = Node(2, n1)
n3 = Node(3, n2)

And a recursive function to get an hierarchy tree:

def get_hierarchy(node, hierarchy_list=[]):
parent = node.parent
if parent:
    hierarchy_list.append(parent)
    return get_hierarchy(parent, hierarchy_list)
else:
    return ', '.join(str(node.id) for node in reversed(hierarchy_list))

If I call the that function outside a loop it works as expected:

hierarchy = get_hierarchy(n3)
print(hierarchy)
# 0, 1, 2

But if I call that function inside a loop, the hierarchy_list varible is not refreshed on each loop:

for i in range(5):
    nodes = [n0, n1, n2]
    hierarchy = get_hierarchy(n3)
    print(hierarchy)
    # 0, 1, 2
    # 0, 1, 2, 0, 1, 2
    # 0, 1, 2, 0, 1, 2, 0, 1, 2
    # 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2
    # 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2

And if I force the hierarchy_list to be empty on each interaction, it works as expected:

for i in range(5):
    nodes = [n0, n1, n2]
    hierarchy = get_hierarchy(n3, []) # forcing to be empty
    print(hierarchy)
    # 0, 1, 2
    # 0, 1, 2
    # 0, 1, 2
    # 0, 1, 2
    # 0, 1, 2

Why python does not refreshes the hierarchy_list on each interaction since I am calling the get_hierarchy function outside get_hierarchy's scope, and if I force it to be a new list it works. And what is the reason for this behavior?

Carlos Porta
  • 1,224
  • 5
  • 19
  • 31

1 Answers1

2

I think the reason is that you are using a mutable argument as the default value in the function, which is a bad idea. The list is initiated only once when the function is defined, not re-initiated every-time you call the function.

The default value of the function argument points to the same list everytime you call that function, so the append method keeps adding to the same list. When you force it to be an empty list, the argument points to a new empty list avoiding the issue you are having.

Have a look here for the same explanation.

stochastic13
  • 423
  • 2
  • 15