Python Linklist with many data - python

I need to implement a linklist to search and add students to an existing group of students. The data students include student ID and name. eg
studentList = [
student = ("11", "John"),
student = ("12", "Cindy"),
student = ("13", "Tracy"),
]
I have the following code so far but it can only be used for a single data, how to include more than one data? How to successfully search for a student?
class Node(object):
def __init__ (self, code, name, n = None):
self.data = code
self.data = name
self.next_node = n
def get_next (self):
return self.next_node
def set_next (self, n):
self.next_node = n
def get_data (self):
return self.data
def set_data (self, d):
self.data = d
class LinkedList (object):
def __init__(self, r = None):
self.root = r
self.size = 0
def get_size (self):
return self.size
def add (self, d):
new_node = Node (d, self.root)
self.root = new_node
self.size += 1
def find (self, d):
this_node = self.root
while this_node:
if this_node.get_data() == d:
return d
else:
this_node = this_node.get_next()
return None
myList = LinkedList()
myList.add(5, "Trevor")
myList.add(10, "Trevor")
print("size="+str(myList.get_size()))
print(myList.find(10))

You can use the built in list. list.append to add to the list and use list comprehension or filters to find in list. see the link https://docs.python.org/2/tutorial/datastructures.html

Below are my modifications. You were missing the string parameter. Also, you had two data variables in your initial code.
class Node(object):
def __init__ (self, code, name, n = None): #here you have code and name
self.data1 = code #you need to change this to data 1
self.data2 = name #you need to change this to data 2 --> they can't have the same name
self.next_node = n
def get_next (self):
return self.next_node
def set_next (self, n):
self.next_node = n
def get_data (self):
return self.data1 # update this to data1 to reflect the code
def set_data (self, d):
self.data1 = d
class LinkedList (object):
def __init__(self, r = None):
self.root = r
self.size = 0
def get_size (self):
return self.size
def add (self, d, s): # have this accept d and s (string)
new_node = Node (d, s, self.root) #include a string parameter
self.root = new_node
self.size += 1
def find (self, d):
this_node = self.root
while this_node:
if this_node.get_data() == d:
return d
else:
this_node = this_node.get_next()
return None

There are a few things wrong with this code (indentation off, parameters not being passed). See the comments:
class Node(object):
def __init__ (self, code, name, n = None):
self.data = code
self.data2 = name # using same variable twice
self.next_node = n
def get_next (self):
return self.next_node
def set_next (self, n):
self.next_node = n
def get_data (self):
return self.data
def set_data (self, d):
self.data = d
class LinkedList (object):
def __init__(self, r = None):
self.root = r
self.size = 0
def get_size (self):
return self.size
def add (self, d, name):
new_node = Node (d, name, self.root) # you didn't pass name which is a required argument
self.root = new_node
self.size += 1
def find (self, d):
this_node = self.root
while this_node:
if this_node.get_data() == d:
return this_node # indentation off, don't you want the node, instead of d?
else:
this_node = this_node.get_next()
return None
myList = LinkedList()
myList.add(5, "Trevor")
myList.add(10, "Trevor")
print("size="+str(myList.get_size()))
print(myList.find(10))
In the future, please post any error messages you have. It seems that your code had thrown an Indentation error when running it.

Related

class return object location instead of the value

I have used a class for a program I have been working on. Unfortunately, I am struggling to return the value instead of the object memory location.
class Node:
def __init__(self, data):
self.data = data
class BinaryTree:
root = None
#classmethod
def InsertNode(cls, data):
newNode = Node(data)
if cls.root == None:
cls.root = newNode
return cls.root
else:
queue = []
queue.append(cls.root)
print(BinaryTree().InsertNode(4))
would return -> <__main__.Node object at 0x000001A8478CAE60>

How can I use Python dependency injection by querying a unique tag (use annotation to register a specific class first)

I am a new user of Python annotation. I am trying to achieve dependency by annotation.
class Trie():
def __init__(self):
self.root = self.Node()
self.count = 0
class Node():
def __init__(self, value=None):
self.value = value
self.children = {}
def add(self, key, value):
path = key.split('.')
node = self.root
for token in path:
if token not in node.children:
node.children[token] = self.Node()
node = node.children[token]
node.value = value
self.count += 1
def get(self, key, default_value=None):
path = key.split('.')
node = self.root
for token in path:
if token not in node.children:
return default_value
node = node.children[token]
self.count -= 1
return node.value
_REGISTRY = Trie()
def register_cls(identifier):
def add_class(cls):
_REGISTRY.add(identifier, cls)
return cls
return add_class
def find_cls(identifier, default_value=None):
return _REGISTRY.get(identifier, default_value)
This is the code to register the class and find the class by class name.
But I do not know how to register a class from another file.
#register_cls('resnet18')
class ResNet18:
def __init__(self):
self.name = 'resnet18'
def get_name(self):
return self.name
if __name__ == '__main__':
name_18 = 'resnet18'
model = find_cls(name_18)
print(model().get_name())
assert model().get_name() == name_18
I can only use this function as this test. find_cls() and #register_cls() in the same file. But this code can store the path of the file, how can I use this function to read the class cross different files.

'Node' object has no attribute 'set_next'

When I insert a new node I get AttributeError: 'Node' object has no attribute 'set_next'. I can't really understand why, because in my Node class I have a method set_next. And isn't that the one I'm calling?
class Node(object):
def __init__(self, val):
self.val = val
self.next = None
def get_data(self):
return self.val
def set_data(self, val):
self.val = val
def get_next(self):
return self.next
def set_next(self, next):
self.next = next
class LinkedList(object):
def __init__(self, head=None):
self.head = head
self.count = 0
def get_count(self):
return self.count
def insert(self, data):
new_node = Node(data)
new_node.set_next()
self.head = new_node
self.count += 1
The expected output is that the new node should be the new head node.
This will fix the AttributeError and the subsequent TypeError.
class Node(object):
def __init__(self, val):
self.val = val
self.next = None
# fixed indentation here
def get_data(self):
return self.val
def set_data(self, val):
self.val = val
def get_next(self):
return self.next
def set_next(self, next):
self.next = next
class LinkedList(object):
def __init__(self, head=None):
self.head = head
self.count = 0
def get_count(self):
return self.count
def insert(self, data):
new_node = Node(data)
# fix logic here
new_node.set_next(self.head)
self.head = new_node
self.count += 1
Testing
linked_list = LinkedList()
linked_list.insert('hello')
linked_list.insert('world')
print(linked_list.count)
print(linked_list.head.val)
print(linked_list.head.next.val)
outputs
2
world
hello
Note that, as you can see, this LinkedList inserts only at the front of the list, not the end.
Bonus
If you want to iterate over the list, use this method
def __iter__(self):
node = self.head
while node is not None:
yield node.val
node = node.next
With your indentation as it stands,
class Node(object):
def __init__(self, val):
self.val = val
self.next = None
def get_data(self):
return self.val
get_data and the following functions, including set_next are local to the __init__ method.
So, as the error says, the "Nodeclass does not have aset_next` method.
You need to pull them back:
class Node(object):
def __init__(self, val):
self.val = val
self.next = None
def get_data(self):
return self.val
#... and the rest
This will give your further problems, but fix your initial problem.
Next, you will see
File "linked.py", line 28, in insert
new_node.set_next()
TypeError: set_next() missing 1 required positional argument: 'next'
As was said in the comments, you need to pass this a value.
I suspect you are trying to set next on the head or final node to this new_node.
I tried this and hope this helps you:
class Node(object):
def __init__(self, val):
self.val = val
self.next = None
def get_data(self):
return self.val
def set_data(self, val):
self.val = val
def get_next(self):
return self.next
def set_next(self, next):
self.next = next
class LinkedList(object):
def __init__(self, head=None):
self.head = head
self.count = 0
def get_count(self):
return self.count
def insert(self, data):
new_node = Node(data)
new_node.set_next(self.head)
self.head = new_node
self.count += 1
>>> itemList = LinkedList()
>>> itemList.insert(38)
>>> itemList.insert(40)
>>> itemList.get_count()
2

Convert string to a linkedlist in Python

This is how I am defining my linkedList
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
I am trying to convert a string to a linkedList
stringTotal = "abc"
head = stringToListNode(stringTotal)
#this method should return a -> b -> c
def stringToListNode(stringTotal):
for i in stringTotal:
currentNode = ListNode(i)
How can I get the next letter of the string and make it the next node?
Try this:
def stringToListNode(stringTotal):
previousNode = None
first = None
for i in stringTotal:
currentNode = ListNode(i)
if first is None:
first = currentNode
if previousNode is not None:
previousNode.next = currentNode
previousNode = currentNode
return first
One nice way to do this might be to define a from_string classmethod on your ListNode class that will recursively build a linked list for you and return the head:
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
#classmethod
def from_string(cls, s):
if s:
n = cls(s[0])
n.next = ListNode.from_string(s[1:])
return n
n = ListNode.from_string('hello')
print(n.next.next.next.next.val)
>>> 'o'
You can create an insert method as an attribute of ListNode, that can be called on the next attribute should that latter already store a node of ListNode:
class ListNode(object):
def __init__(self, x=None):
self.val = x
self.next = None
def insert(self, val):
if self.val is None:
self.val = val
else:
getattr(self.next, 'insert', lambda x:setattr(self, 'next', ListNode(x)))(val)
def __str__(self):
return '{}, {}'.format(self.val, str(self.next) if self.next else '')
def __repr__(self):
return 'List(<{}>)'.format(str(self))
#classmethod
def insert_vals(cls, s):
l = cls()
for i in s:
l.insert(i)
return l
_list = ListNode.insert_vals('abc')
print(_list)
Output:
List(<a, b, c, >)
Note, however, that the operation accomplished in method insert can also be performed as a simple function, however, it is not as clean as an instance attribute:
class ListNode(object):
def __init__(self, x=None):
self.val = x
self.next = None
def __str__(self):
return '{}, {}'.format(self.val, str(self.next) if self.next else '')
def __repr__(self):
return 'List(<{}>)'.format(str(self))
def insert_val(_l:ListNode, value:str) -> None:
if _l.val is None:
_l.val = value
else:
if isinstance(_l.next, ListNode):
insert_val(_l.next, value)
else:
_l.next = ListNode(value)
_l = ListNode()
for i in 'abc':
insert_val(_l, i)
>>>_l
Output:
List(<a, b, c, >)

Printing Linked List

I have the following Linked List implementation. There is a problem with the printlist() function. The while loop is turning an error that there is no attribute next for self. Is there a better way to write this function? Thank you!!!
class Node:
def __init__(self, data, next=None):
self.data=data
def _insert(self, data):
self.next=Node(data)
def _find(self, data):
if self.data==data:
return self
if self.next is None:
return None
while self.next is not None:
if self.next.data==data:
return self.next
return None
def _delete(self, data):
if self.next.data == data:
temp=self.next
self.next =self.next.next
temp=None
def _printtree(self):
while self:
print self.data,
self=self.next
class LinkedList:
def __init__(self):
self.head=None
def insert(self, data):
if self.head:
self.head._insert(data)
else:
self.head=Node(data)
def find(self, data):
if self.head.data==data:
return self.head
return self.head._find(data)
def delete(self, data):
if self.head.data==data:
head=None
return
self.head._delete(data)
def printtree(self):
self.head._printtree()
add next attribute to Node's ini method
you should define printtree of LinkedList this way:
def printree(self):
current_node = self.head
print current_node.data
while current_node.next is not None:
print current_node.next.data
current_node = current_node.next
adding a repr method will make your code nicer

Categories

Resources