Reputation: 29
Im trying to make a linked list in python and would like to print out the things but its printing as a memory location. We learnt how to fix this in class but im on half term at the moment and have nobody to ask.
An example of what im currently getting:
List: <__main__.LinkedList object at 0x02EA0100>
index: 0 data: 1 item: <__main__.Node object at 0x02EA00D0> pointer: <__main__.Node object at 0x02EA0148>
index: 1 data: 6 item: <__main__.Node object at 0x02EA0148> pointer: <__main__.Node object at 0x02EA0190>
index: 2 data: 3 item: <__main__.Node object at 0x02EA0190> pointer: None
This is not very usefull to me.
The method im using to get this masterpice:
def PrintList(self):
item = self.list_start
index = 0
print(f"List: {self}")
while item:
print(
f"\t index: {index}\t data: {item.data}\t item: {item}\t pointer: {item._get_pointer()}"
)
item = item._get_pointer()
index += 1
Im sure theres something wrong in the print line i just cant spot it.
I know your not supposed to put loads of code on here but i need to give context
Node Class:
class Node:
def __init__(self, data=None, pointer=None):
self.data = data
self.poiner = pointer
def PrintNode(self):
print(f"Node Data: {self.data}\t self: {self}\t pointer: {self.pointer}\n")
def _set_pointer(self, pointer):
self.pointer = pointer
def _get_pointer(self):
return self.pointer
LinkedLis Class:
class LinkedList:
def __init__(self):
self.list_start = None
def PrintList(self):
item = self.list_start
index = 0
print(f"List: {self}")
while item:
print(
f"\t index: {index}\t data: {item.data}\t item: {item}\t pointer: {item._get_pointer()}"
)
item = item._get_pointer()
index += 1
def _isleagl(self, node):
if node is None:
print(f"node' is None")
return False
elif type(node) != Node:
print(f"'node' has worng type: {type(node)}")
return False
else:
return True
def AppendNode(self, node):
if self._isleagl(node):
if self.list_start == None:
self.list_start = node
node._set_pointer(None)
else:
item = self.list_start
while item:
if item == node:
node = copy.deepcopy(node)
elif item._get_pointer() is None:
item._set_pointer(node)
node._set_pointer(None)
break
else:
item = item._get_pointer()
def DeleteNode(self, node):
if self._islegal(node):
if self.list_start == node:
self.list_start = node._get_pointer()
else:
item = self.list_start
while item:
if item._get_pointer() == node:
item._set_pointer(node._get_pointer())
break
item = item._get_pointer()
Menu system: #i dont think this is going to be of much help
def main():
my_list = None
my_node = None
while True:
print("Node Manipulations")
print("\t 0: Create Node")
print("\t 1: Set Node Data")
print("\t 2: Print Node")
print()
print("List Manipulations")
print("\t 3: Create List")
print("\t 4: Print List")
print("\t 5: Append Node to List")
print("\t 6: Delete Node from List")
print()
print("X: EXIT Program")
choice = input("->")
if choice not in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "X", "x"]:
continue
if choice == "X" or choice == "x":
break
elif choice == "0":
my_node = Node()
elif choice == "1":
if my_node is None:
print("Create Node first")
else:
my_node.data = input("Node Data? -> ")
elif choice == "2":
if my_node is None:
print("Create Node first")
else:
my_node.PrintNode()
elif choice == "3":
my_list = LinkedList()
elif choice == "4":
if my_list is None:
print("Create List first")
else:
my_list.PrintList()
print()
elif choice == "5":
if my_list is None:
print("Create List first")
else:
my_list.AppendNode(my_node)
elif choice == "6":
if my_list is None:
print("Create List first")
else:
my_list.DeleteNode(my_node)
Upvotes: 0
Views: 1527
Reputation: 357
"<main.K object at 0x01481FE8>"
try
xyz=str(x.data)
print(xyz)
xyz will give you data stored at that location.
use it in loop if you are using an list or any data structure.
faced similar problem in a program it helped.
Upvotes: 0
Reputation: 4644
Try running the following code:
class K:
pass
obj = K()
print(obj)
The output is:
<__main__.K object at 0x01481FE8>
By default, if you don't write a "to string" method (or __str__()
) the garbage above is what python will produce as a string. Note that the function print
can only print strings. It cannot print integers, or anything else. As such print(n)
will convert all inputs to strings before printing them. The code below describes what the built-in print
function does:
import sys
def print(*args, sep=" ", end"\n", file=sys.stdout):
file.write(sep.join(map(str, args)) + end)
So, write your own __str__
method:
import sys
import io
class Node:
def __init__(self, data=None, pointer=None):
self.data = data
self.pointer = pointer
def print_node(self, *, sep="\t", file=sys.stdout):
print(
f"Node Data: {self.data}",
f"self: {id(self)}",
f"pointer: {id(self.pointer)}",
sep=sep,
file=file
)
def _set_pointer(self, pointer):
self.pointer = pointer
def _get_pointer(self):
return self.pointer
def __str__(self):
with io.StringIO() as string_stream:
self.print_node(file=string_stream)
stryng = string_stream.getvalue()
return stryng
Your print node method was originally named PrintNode
. Never begin something with a capital letter unless it is a class. Either write printNode
or print_node
.
Secondly, I changed f"pointer: {self.pointer}"
to f"pointer: {id(self.pointer)}"
Suppose that you did not do that. Well then, print_node
would print self.pointer
. But self.pointer
is a node, so it would then print self.pointer.pointer
. But self.pointer.pointer
is a node, so then it would print self.pointer.pointer.pointer
, and so on... You don't want that. The memory address of an object can be retrieved with the id()
function.
Also, it's a bad idea for print_node
to print self. That's just begging for an infinite recursion. How do I print self
? well, I print data
, self
, and pointer
. That means I gotta print self
, which means I gotta print self
, which means I gotta print self
, and so on, forever, and ever.
Upvotes: 1