Tree node structure:
class BPlusNode:
def __init__(self,isleaf = True,val=[],parent=None,children=[]):
self.values = val
self.children = children
self.parent = parent
self.isleaf = isleaf
self.order=3
where the bug appears:
def split(self,node):
if (len(node.children)==0 and len(node.values) <= self.order) or (len(node.children)!=0 and len(node.values) < self.order):
return
if node.parent==None:
#if current node is the root , create a new node as root
new_root=BPlusNode(isleaf=False) #something wrong this line
global CNT
CNT+=1
if(CNT>5):
sys.exit()
print('<debug>',new_root.values)
node.parent=new_root
self.root=new_root
parent=new_root
input 3,1,4,5 in order the output is: the output strangely the new node has already been assigned values
but the program runs correctly if I write like this:
new_root=BPlusNode(isleaf=False,val=[],parent=None,children=[])
Why does this happens?
I noticed a mechanism of default parameter in python: operations on mutable objects with default parameters will be preserved for example:
cnt=2
def f(data=[]):
global cnt
data.append(1)
print(data)
data[0]=cnt
cnt+=1
return data
f()
f()
f()
the output will be:
[1]
[2, 1]
[3, 1, 1]
but in my code:
def __init__(self,isleaf = True,val=[],parent=None,children=[]):
the parameter "val" has not been operated
Is this problem related to this mechanism? Or it is caused by other reasons?
Yes, mutable default arguments are initialized when the function/method is defined so every
BPlusNodethat uses the mutable defaults receives the same list.Instead use the following to avoid mutable defaults:
This will assign a new empty list if the default is
None, otherwise use the default.It runs correctly here:
Because the default isn't used, and you explicitly pass in new list objects.