I am trying to create a piece of code that can print out a linked list in different ways depending on how its called and from where in the list you choose to start.
To do this I have chosen a recursive function that you pass data to in the initial call, and it passes that data and more through its recursive calls in order to build up the desired output form. However when I try and recursively call the function, the 'self' argument appears to send twice, writing itself into the first two arguments in the function.
class LinkedList(object):
def __init__(self):
self.head = Node()
self.allNodeLocations = {}
def buildLinkedList(self, curNode, finish=99999, between=False, location=[0, 0], allNodeLocations={}, i=0):
def __init__(self, name):
self.curNode = curNode
self.finish = finish
self.between = between
self.location = location
self.allNodeLocations = allNodeLocations
self.i = i
if len(curNode.getChildren()) > 1:
for child in curNode.getChildren():
location, allNodeLocations, i = self.buildLinkedList(self, child, finish, between,
location, allNodeLocations, i) #THIS IS WHERE THE CODE FAILS
location[0] -= 1
i -= 1
return location, allNodeLocations, i
In the above case, the 'child' variable should be a Node object. Running the above script gives "TypeError: buildLinkedList() takes from 2 to 7 positional arguments but 8 were given"
If instead I call the function with the line
self.buildLinkedList(self, child)
And check the values with pycharm debugger, both self, and the curNode (ie the child variable) both point to the same LinkedList object and the next variable in the function definition heading 'finish' contains the node object that child passed to the function that should instead be input under the curNode variable.
Please note I have removed a large amount of my code to make it easier to read here, the remainder of the code is below if need be. I apologise that there is currently a large amount of useless code, I intend on doing things with it in the future...
class Node(object):
def __init__(self, busNum = None, data=None, children=None, parents=None):
self.busNum = busNum
self.data = data
self.children = []
self.parents = []
if children:
self.children += children
if parents:
self.parents += parents
def getChildren(self):
return self.children
def getParents(self):
return self.parents
def setChild(self, child):
self.children.append(child)
def setParent(self, parent):
self.children.append(parent)
def getData(self):
return self.data
def setData(self, data):
self.data = data
def toString(self):
return "Bus Number: " + str(self.busNum) + ", Data: " + str(self.data)
class LinkedList(object):
def __init__(self):
self.head = Node()
self.allNodeLocations = {}
# self.curLocation = [0, 0]
def addBus(self, bus, data, children, parents):
newNode = Node(bus, data, children, parents)
def buildLinkedList(self, curNode, finish=99999, between=False, location=[0, 0], allNodeLocations={}, i=0):
def __init__(self, name):
self.curNode = curNode
self.finish = finish
self.between = between
self.location = location
self.allNodeLocations = allNodeLocations
self.i = i
allNodeLocations[curNode] = location
if i >= finish:
return allNodeLocations
if len(curNode.getChildren()) == 0:
# If there are no children, set the location of the current bus, and go down a y level
# location[0] -= 1
location[1] += 1
# i -= 1
# curNode = prevNode
return location, allNodeLocations, i
elif len(curNode.getChildren()) == 1:
# If there is 1 child, set its location and move onto its next child, once we return from there,
# subtract 1 from the current iteration and x location
location[0] =+ 1
i =+ 1
if i > finish:
i -= 1
return location, allNodeLocations, i
# prevNode = curNode
curNode = curNode.getChildren()[0]
location, allNodeLocations, i = self.buildLinkedList(self, curNode, finish, between, location, allNodeLocations, i)
location[0] -= 1
i -= 1
return location, allNodeLocations, i
elif len(curNode.getChildren()) > 1:
i += 1
location[0] += 1
for child in curNode.getChildren():
location, allNodeLocations, i = self.buildLinkedList(self, child, between=False)#, finish, between, location, allNodeLocations, i)
location[0] -= 1
i -= 1
return allNodeLocations
e=Node(4,11)
f=Node(5,11)
g=Node(6,11)
h=Node(8,11)
j=Node(10,11)
k=Node(11,11)
i=Node(7,33,[h])
d=Node(9,66,[j,k])
c=Node(3,66,[i])
b=Node(2,132,[e,f,g])
a=Node(1,66,[b,c])
listOfNodes = [a,b,c,d,e,f,g,h,i,j,k]
print(d.getChildren())
# d.setChild(11)
# g.setChild(9)
# i.setParent(4)
# print(d.getChildren())
linkd=LinkedList()
linkd.buildLinkedList(a)
--Update-- The issue was pointed out by user Moxy, the fix was to remove the call to self within the buildLinkedList call.
As an aside, when I run the script, it creates a dictionary with the 'location' variable, in each iteration, however, whenever the location variable updates, it updates all instances of it in the dictionary.
To clarify, I make the dictionary recursively with the line "allNodeLocations[curNode] = location", with the curNode and location variables being updated on each recursive call, however when location changes, it immediately updates the dictionary to be the same value throughout each cell in the dictionary.
Is there some way to just get the value of the location variable instead the pointer (if thats even what the issue is)?
When you call buildLinkedList
remove the self
. It represents the instance of the class so you add it when you create the function inside your class but never when you call it. If you add the self
, it creates an offset in the parameters of buildLinkedList
.
Try this instead:
self.buildLinkedList(curNode, finish, between, location, allNodeLocations, i)
After fixing this, you will have a
ValueError: too many values to unpack (expected 3)
To fix it replace the last return
of the buildLinkedList
by something like:
return None, allNodeLocations, None
--Update--
This issue of update is because the list are passed by reference and not value, to fix it try:
allNodeLocations[curNode] = location by allNodeLocations[curNode] = list(location)
or
allNodeLocations[curNode] = location by allNodeLocations[curNode] = location[:]
Btw, I don't understand what you mean by getting the value of location instead of the pointer
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.