hope somebody can give me a hint here - so i have a Node class that should receive 1 mandatory value and one optional one. The idea is to return a linked list
class Node(object):
def __init__(self, value, next_node = None):
self.value = value
self.next_node = next_node
def get_next(self):
return self.next_node
Now i'm using this class to create a linked list like:
Z = Node('Z')
Y = Node('Y', Z)
X = Node('X', Y)
W = Node('W', X)
Now I want to write a function that receives the head of the list and prints it:
def print_reverse(head):
current = head
my_list = []
while current:
current = current.next_node
u = Node(current)
my_list.append(u.value)
print my_list
print_reverse(W)
The problem I'm facing is that i get back the memory address instead of the actual value.
[<__main__.Node object at 0x1033eb390>, <__main__.Node object at 0x1033eb350>, <__main__.Node object at 0x1033eb310>, None]
Basically I don't know how to instantiate the value of the Node. I would want to get back this
[ W, X, Y , Z, None]
class Node(object):
def __init__(self, value, next_node = None):
self.value = value
self.next_node = next_node
def get_next(self):
return self.next_node
def print_reverse(head):
current = head
my_list = []
my_list.append(current.value)
while current.next_node != None:
current = current.next_node
my_list.append(current.value)
print my_list
Z = Node('Z')
Y = Node('Y', Z)
X = Node('X', Y)
W = Node('W', X)
print_reverse(W)
This runs and prints ['W','X','Y','Z'] for me.
You need implement repr which should return a printable representation of the object. eg.
class Node(object):
def __init__(self, value, next_node = None):
self.value = value
self.next_node = next_node
def get_next(self):
return self.next_node
def __repr__(self):
return self.value
https://docs.python.org/2/reference/datamodel.html#object.repr
Related
I have a simple node class with Id and Value, but python seems to not be able to access those attributes when i use the objects in a list. This is the class Node for context.
class Node():
def __init__(self, id : int, value : int):
self.id = id
self.value = value
This is a priority queue implementation (or at least a try to do so) where the error comes from
class ListAlt():
def __init__(self):
self.queue = [Node]
def append(self, node : Node):
self.queue.append(node)
def dequeue(self):
idMax = 0
i = 0
for nodo in self.queue:
if (nodo.value > self.queue[idMax].value):
idMax = i
i += 1
result = self.queue[idMax]
return result
And this is the full code
#!/usr/bin/python3
class Node():
def __init__(self, id : int, value : int):
self.id = id
self.value = value
class ListAlt():
def __init__(self):
self.queue = [Node]
def append(self, node : Node):
self.queue.append(node)
def dequeue(self):
idMax = 0
i = 0
for nodo in self.queue:
if (nodo.value > self.queue[idMax].value):
idMax = i
i += 1
result = self.queue[idMax]
return result
n1 = Node(1,10)
n2 = Node(2,3)
n3 = Node(3,6)
lista = ListAlt()
lista.append(n1)
lista.append(n2)
lista.append(n3)
print(lista.dequeue())
Now, i can access the values of n1,n2,n3 directly, but inside the ListAlt object in this exact line
if (nodo.value > self.queue[idMax].value):
it throws the exception saying "AttributeError: type object 'Node' has no attribute 'value'"
it should have printed "10" if everything worked correctly.
This is the problem:
class ListAlt():
def __init__(self):
self.queue = [Node] # <--
You are setting queue to a list containing the Node class. Why not just an empty list?
Also, dequeue returns a Node instance. So to get 10, you need to write this instead:
print(lista.dequeue().value)
Here is how I would change that code:
class Node:
def __init__(self, node_id: int, value: int) -> None:
self.id = node_id
self.value = value
class ListAlt:
def __init__(self) -> None:
self.queue: list[Node] = []
def append(self, node: Node) -> None:
self.queue.append(node)
def dequeue(self) -> Node:
id_max = 0
i = 0
for nodo in self.queue:
if nodo.value > self.queue[id_max].value:
id_max = i
i += 1
result = self.queue[id_max]
return result
if __name__ == "__main__":
n1 = Node(1, 10)
n2 = Node(2, 3)
n3 = Node(3, 6)
lista = ListAlt()
lista.append(n1)
lista.append(n2)
lista.append(n3)
print(lista.dequeue().value)
You are initializing your queue with the type Node. So, it is trying to get the value attribute of the type, which does not exist. Change your code with:
class ListAlt():
def __init__(self):
self.queue = []
...
So i started learning about listNodes or linked lists in python and created one;
class Node:
def __init__(self, data, next = None):
self.data = data
self.next = next
class LinkedNode:
def __init__(self):
self.head = None
self.size = 0
def add(self, data):
self.head = Node(data, self.head)
self.size += 1
It works fine but how can i get a listNode in python as the result of this node.
What i mean is a list node looks like this;
{val: 'some_val', next: {val: 'other_val', next{...}}}
In js, when we print the instance of the list node class, it gets the result in the same format but, in python when i tried the same;
ln = LinkedNode()
print(ln)
It gives this;
<main.LinkedNode object at 0x7fe191576400>
There are several ways to make your instance print something more useful.
For instance, you could add a method that will produce a dict, because dictionaries are printed in an output format that is similar to what you ask for:
class Node:
def __init__(self, data, next = None):
self.data = data
self.next = next
def asdict(self):
return { "data": self.data, "next": self.next and self.next.asdict() }
So now when you do this:
print(Node(1).asdict())
... you'll get:
{'data': 1, 'next': None}
When you also add such a method to the LinkedNode class:
class LinkedNode:
def __init__(self):
self.head = None
self.size = 0
def add(self, data):
self.head = Node(data, self.head)
self.size += 1
def asdict(self):
return self.head and self.head.asdict()
...you can do:
lst = LinkedNode()
lst.add(1)
lst.add(2)
print(lst.asdict())
And that will output:
{'data': 2, 'next': {'data': 1, 'next': None}}
And finally, if you want this output to be the default that print will use when you just do print(lst), then define __repr__ (or __str__) on the class:
class LinkedNode:
def __init__(self):
self.head = None
self.size = 0
def add(self, data):
self.head = Node(data, self.head)
self.size += 1
def asdict(self):
return self.head and self.head.asdict()
def __repr__(self):
return repr(self.asdict())
Now you can do print(lst) without calling .asdict() explicitly, and get that same output.
I am trying to print a specific path between the node and leaf. I have created a class n-tree (tree to have multiple n-children) but when I run my function, it tells me
AttributeError: 'list' object has no attribute 'data'
This is my code:
class Node(object):
def __init__(self, data):
self.data = data
self.children = []
self.left = None
self.right = None
def add_child(self, obj):
self.children.append(obj)
def hasPath(root, arr, x):
if (not root):
return False
arr.append(root.data)
if(root.data == x):
return True
if(hasPath(root.left, arr, x) or hasPath(root.right, arr, x)):
return True
arr.pop(-1)
return False
def printPath(root, x):
arr = []
if(hasPath(root, arr, x)):
for i in range(len(arr) - 1):
print(arr[i], end = "->")
print(arr[len(arr) - 1])
else:
return []
I am still a beginner at this so I don't really understand how classes work. Any help would be appreciated.
I need some help writing an __iter__() method for my UnorderedList() class. I tried this:
def __iter__(self):
current = self
while current != None:
yield current
But the while loop doesn't stop. Here is the rest of my classes and code:
class Node:
def __init__(self,initdata):
self.data = initdata
self.next = None
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self,newdata):
self.data = newdata
def setNext(self,newnext):
self.next = newnext
class UnorderedList:
def __init__(self):
self.head = None
self.count = 0
If you want to iterate all items succeedingly, you should do
def __iter__(self):
# Remember, self is our UnorderedList.
# In order to get to the first Node, we must do
current = self.head
# and then, until we have reached the end:
while current is not None:
yield current
# in order to get from one Node to the next one:
current = current.next
so that in every step you go one step further.
BTW, setters and getters aren't used in Python in the form of methods. If you need them, use properties, otherwise omit them altogether.
So just do
class Node(object):
def __init__(self, initdata):
self.data = initdata
self.next = None
class UnorderedList(object):
def __init__(self):
self.head = None
self.count = 0
def __iter__(self):
current = self.head
while current is not None:
yield current
current = current.next
class Node:
def __init__(self, tree, data, parent=None):
self.data = data
self.parent = parent
self.children = []
self.tree = tree
def find(self, x):
if self.data is x:
return self
elif self.children:
for node in self.children:
return node.find(person)
else:
return None
I am really stuck, i can't seem to create a method in my Node class that finds a Node with data x and returns that Node. If no Node is found, it will return None.
you're searching for parent in children, while you should search for x
class Node():
def __init__(self, tree, data, parent=None):
self.data = data
self.parent = parent
self.children = []
self.tree = tree
def find(self, x):
if self.data is x: return self
for node in self.children:
n = node.find(x)
if n: return n
return None
>>> n = Node(None, 1)
>>> n.children = [Node(None, 2), Node(None, 3)]
>>> print n.find(3).data
3
I think the immediate fix would be to change this
for node in self.children:
return node.find(person)
To this
for node in self.children:
res = node.find(person)
if res is not None:
return res