Node object isn't callable. Please resolve - python

#Linked List
class Node:
def __init__(self,item):
self.item = None
self.next = item
class Linked:
def __init__(self):
self.head = None
def printlist(self):
printval = self.head
while printval is not None:
printval(printval.item)
printval = printval.next
def insertion(self,newitem):
NewNode = Node(newitem)
NewNode.next = self.head
self.head = NewNode
def InsertBetween(self,Middle_Node,newitem):
if Middle_Node is None:
print("Value doesn't exist in node")
return
NewNode = Node(newitem)
NewNode.next = Middle_Node.next
Middle_Node.next = NewNode
listy = Linked()
listy.head = Node(20)
p2 = Node(21)
p3 = Node(22)
listy.head.next = p2
p2.next = p3
listy.InsertBetween(listy.head.next,40)
listy.insertion(45)
listy.printlist()
I'm getting this error:
Traceback (most recent call last):
File "c:\Users\Tanishq\Desktop\Python Practice SORTS\LList.py", line 41, in <module>
listy.printlist()
File "c:\Users\Tanishq\Desktop\Python Practice SORTS\LList.py", line 15, in printlist
printval(printval.item)
TypeError: 'Node' object is not callable

I think there are two mistakes in your code:
You are setting the variable item to None for every node and next to an int value.
The correct way would be the other way around
class Node:
def __init__(self,item):
self.item = item
self.next = None
In printlist there seems to be a typo printval should be print
print(printval.item)
I am assuming you are trying to implement a linked list and the above changes should get you the desired result

Related

Python linked-list issues of receiving memory addresses when printing unless double calling

I am creating a Linked List implementation and I cannot fix this error of having to double call node.val.val to print the data instead of the memory address.
Here is my implementation:
class LinkedNode:
def __init__(self, val, nxt=None):
self.val = val
self.nxt = nxt
class LinkedList:
def __init__(self, head=None):
self.head = head
def append(self, new_val):
node = LinkedNode(new_val, None)
if self.head:
curr = self.head
while curr.nxt:
curr = curr.nxt
curr.nxt = node
else:
self.head = node
def print(self):
curr = self.head
while curr:
**print(curr.val)**
curr = curr.nxt
l1 = LinkedList()
l1.append(LinkedNode(2))
l1.append(LinkedNode(3))
l1.append(LinkedNode(4))
l1.print()
When the line in the print function is "print(curr.val)", the function prints memory addresses. When the line is "print(curr.val.val)", the function prints 2,3,4.
Does anyone have a possible solution?
You were passing a LinkedNode() object as an argument to .append() function:
class LinkedNode:
def __init__(self, value, nxt=None):
self.val = value
self.nxt = nxt
class LinkedList:
def __init__(self, head=None):
self.head = head
def append(self, new_val):
node = LinkedNode(new_val, None) #Creation of LinkedNode from integer
if self.head:
curr = self.head
while curr.nxt:
curr = curr.nxt
curr.nxt = node
else:
self.head = node
def print(self):
curr = self.head
while curr:
print(curr.val)
curr = curr.nxt
l1 = LinkedList()
l1.append(2) #Argument must be integer, not LinkedNode(integer)
l1.append(3) #Because you are already converting integer to LinkedNode on append function
l1.append(4)
l1.print()
Output:
2
3
4
Because in these lines you are creating LinkedNode objects not values!
l1.append(LinkedNode(2))
l1.append(LinkedNode(3))
l1.append(LinkedNode(4))
After that, you created a new LinkedNode(LinkedNode(2), None) within the scope of the append function.
Change it to:
l1.append(2)
l1.append(3)
l1.append(4)

calling a method in another method errors

class Node:
def __init__(self, data):
self.data = data
self.ref = None
class LinkedList:
def __init__(self):
self.head = None
def show(self):
if self.head is None:
print("This linked lists is empty")
else:
currentnode = self.head
while currentnode is not None:
print(currentnode.data, end=" --> ")
currentnode = currentnode.ref
def addelement(self, value):
newnode = Node(value)
newnode.ref = self.head
self.head = newnode
def lenofll(self , i = 0):
while self.head is not None:
i = i +1
self.head = self.head.ref
return i
def middle(self):
i = 0
lent = self.lenofll()
if self.head is None: # self.head changed to None after calling lenofll method.
print("linked list is empty")
I wanted to get the length of linked lists in the middle method. But as I called self.lenofll(), it changed the self.head to None.
What can I do to fix this?
Indeed, doing self.head = self.head.ref modifies the head. You should not make any modifications to self.head in a method whose job is just to search in the list -- without modifying anything to it.
As you can see, that method keeps looping until self.head is not None is not true, i.e. when self.head is None. No wonder that self.head is None after running this method!
Use a local variable for this iteration instead:
def lenofll(self, i = 0):
node = self.head # use local variable
while node is not None:
i += 1
node = node.ref
return i

Double LinkedList in Python

I have been trying to implement double linked list in Python. I have a problem in removing a node from any given position. Please help. Below is my code.
class Double_linked_list:
class Node:
__slots__ = '_element', '_prev', '_next'
def __init__(self, element, prev, next):
self._element = element
self._next = next
self._prev = prev
def __init__(self):
self._head = self.Node(None, None, None)
self._tail = self.Node(None, None, None)
self._head._next = self._tail
self._tail._prev = self._head
self._size = 0
def __len__(self):
return self._size
def is_empty(self):
return self._size == 0
def delete_any(self, pos):
if self.is_empty():
raise Empty('Linked List empty')
thead = self._head
i = 1
while i < pos - 1:
thead = thead._next
i += 1
value = thead._next._element
thead._next = thead._next._next
thead._next._next._prev = thead._prev
self._size -= 1
return value
Exception:
Traceback (most recent call last):
File "C:\Users\Abdullah Khan\AppData\Local\Programs\Python\Python37-32\lib\site-packages\IPython\core\interactiveshell.py", line 3326, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-2-277dd1818f6d>", line 1, in <module>
runfile('C:/Users/Abdullah Khan/Documents/Python Learning/Starting from Scratch/data structures and algos/linkedlist/double_linked_list.py', wdir='C:/Users/Abdullah Khan/Documents/Python Learning/Starting from Scratch/data structures and algos/linkedlist')
File "C:\Program Files\JetBrains\PyCharm 2019.1.3\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File "C:\Program Files\JetBrains\PyCharm 2019.1.3\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/Users/Abdullah Khan/Documents/Python Learning/Starting from Scratch/data structures and algos/linkedlist/double_linked_list.py", line 119, in <module>
print("Deleted Any: ", dll.delete_any(3))
File "C:/Users/Abdullah Khan/Documents/Python Learning/Starting from Scratch/data structures and algos/linkedlist/double_linked_list.py", line 90, in delete_any
thead._next._next._prev = thead._prev
AttributeError: 'NoneType' object has no attribute '_next'
I'm guessing you're hitting the end of your list. You probably need to have some checks that each of those thead._next items are not None. For instance, if you want to delete the second-to-last element in your list, thead._next is the last element, and thead._next._next is None.
Ultimately it looks like you are assuming you have at least three _next elements in the list, thead._next = thead._next._next followed by thead._next._next._prev gives the original thead._next._next._next._prev.
Try this:
def delete_any(self, pos):
if self.is_empty():
raise Empty('Linked List empty')
if pos > self._size - 1:
# A one-element list only has position 0, thus size - 1.
raise IndexError('Position is out of range')
thead = self._head
for i in range(pos - 1):
# This should be fine as long as the above check passed.
thead = thead._next
value = thead._next._element
thead._next = thead._next._next
if thead._next._next is not None:
# If you run off your list, you just don't have another element
# on which to define `_prev`.
thead._next._next._prev = thead._prev
self._size -= 1
return value
Note I couldn't run this without some example code to build the list and get your error. Let me know if there are issues and I'll try to correct them.
Also note that this won't work with a one-element list. You're assuming you can stand at the element before the one that you want to delete, but in a one-element list you can't do that. You might want to add code to handle that as a special case.
Look here this works fine
class Node:
def __init__(self, data):
self.item = data
self.next = None
self.prev = None
class doublyLinkedList:
def __init__(self):
self.start = None
def InsertToEmptyList(self, data):
if self.start is None:
new_node = Node(data)
self.start = new_node
else:
print("The list is empty")
def InsertToEnd(self, data):
# Check if the list is empty
if self.start is None:
new_node = Node(data)
self.start = new_node
return
temp = self.start
while temp.next is not None:
temp = temp.next
new_node = Node(data)
temp.next = new_node
new_node.prev = temp
def DeleteAtStart(self):
if self.start is None:
print("The Linked list is empty, no element to delete")
return
if self.start.next is None:
self.start = None
return
self.start = self.start.next
self.start_prev = None;
def delete_at_end(self):
# Check if the List is empty
if self.start is None:
print("The Linked list is empty, no element to delete")
return
if self.start.next is None:
self.start = None
return
temp = self.start
while temp.next is not None:
temp = temp.next
temp.prev.next = None
def delet_at_any(self,position):
temp=self.start
while position>2:
temp=temp.next
position-=1
prev=temp
temp.next=temp.next.next
temp.prev=prev
def Display(self):
if self.start is None:
print("The list is empty")
return
else:
temp = self.start
while temp is not None:
print("Element is: ", temp.item)
temp = temp.next
print("\n")
NewDoublyLinkedList = doublyLinkedList()
NewDoublyLinkedList.InsertToEmptyList(10)
NewDoublyLinkedList.InsertToEnd(20)
NewDoublyLinkedList.InsertToEnd(30)
NewDoublyLinkedList.InsertToEnd(40)
NewDoublyLinkedList.InsertToEnd(50)
NewDoublyLinkedList.InsertToEnd(60)
NewDoublyLinkedList.Display()
NewDoublyLinkedList.DeleteAtStart()
NewDoublyLinkedList.DeleteAtStart()
NewDoublyLinkedList.delet_at_any(3)
NewDoublyLinkedList.Display()
class node :
def __init__(self, data):
self. data = data
self.next = None
self.prev = None
class doubleLinkedList:
def __init__(self):
self.head = None
def insertNode(self, data):
newNode = node(data)
if self.head == None:
self.head = newNode
else:
current = self.head
while current.next is not None:
# prevNode = current
current = current.next
newNode.prev = current
current.next = newNode
def printDLL(self):
current = self.head
count = 0
while current.next is not None:
count+=1
if count == 1:
print("NONE<----",current.data,end="--->")
else:
print(current.data,end="--->")
current = current.next
if count ==0:
print("NONE<----",current.data,'----> NONE')
else:
print(current.data,'----> NONE')
def goToNode(self,data):
current = self.head
count = 1
while current.next is not None:
if count == data:
print("cEntered node data :", current.data)
print("prev node data :", current.prev.data)
print("next node data :", current.next.data)
break
else:
count+=1
current = current.next
l = doubleLinkedList()
l.insertNode(1)
l.insertNode(2)
l.insertNode(3)
l.insertNode(4)
l.insertNode(5)
l.insertNode(6)
l.insertNode(7)
l.insertNode(8)
l.printDLL()
l.goToNode(5)

What's wrong with the code although i have defined the function already?

this code gives NameError showing i havenot defined the function but i actually defined the function in a class.
I tried alot but couldnot resolve it.
class Node(object):
def __init__(self, data):
self.data = data
self.next = None
class LinkedList(object):
def __init__(self):
self.head = None
def printList(self):
temp = self.head
while temp:
print(temp.data)
temp = temp.next
def append(self, new_data):
new_node = Node(new_data)
if self.head is None:
self.head = new_node
return
last = self.head
while last.next:
last = last.next
last.next = new_node
def merge(self, head1, head2):
temp = None
if head1 is None:
return head2
if head2 is None:
return head1
if head1.data <= head2.data:
temp = head1
temp.next = merge(head1.next, head2)
else:
temp = head2
temp.next = merge(head1, head2.next)
return temp
list1 = LinkedList()
list1.append(10)
list1.append(20)
list1.append(30)
list1.append(40)
list1.append(50)
list2 = LinkedList()
list2.append(5)
list2.append(15)
list2.append(18)
list2.append(35)
list2.append(60)
list3 = LinkedList()
list3.head = merge(list1.head, list2.head)
print("Merged Linked List is : ")
list3.printList()
NameError Traceback (most recent call last)
<ipython-input-11-22fca0a2d24d> in <module>()
57
58 list3 = LinkedList()
---> 59 list3.head = merge(list1.head, list2.head)
60
61 print("Merged Linked List is : ")
NameError: name 'merge' is not defined
You have defined merge as a method of the LinkedList class. That means you need to call it on an instance of the class, not just by itself. For instance, you could replace the merge(...) call causing your current exception with list3.merge(...), and the recursive call inside the method with self.merge(...).
But I'm not really sure it needs to be a method, so you could instead move the function definition out of the class (and remove its self parameter). It would work just fine as a stand-alone function.

Intersection of two sorted Linked lists in python3?

My code is unable two print out the new list which is the intersection of two sorted linked list.Its not able to access list inside the function. Please point out the mistake in my code. there is no indentation problem in my code and the algorithm also seems to be fine.
class Node(object):
def __init__(self,data):
self.data = data
self.next = None
class Linked(object):
def __init__(self):
self.head = None
def push(self,n):
new_node = Node(n)
new_node.next = self.head
self.head = new_node
def print_list(self):
current = self.head
while current:
print(current.data)
current = current.next
def intersect(self,l1,l2):
l1 = l1.head
l2 = l2.head
dummy = cur = Node(0)
while l1 and l2:
if l2.data>l1.data:
l1=l1.next
elif l1.data>l2.data:
l2=l2.next
else:
cur.next = l1 or l2
l1 = l1.next
l2 = l2.next
cur = cur.next
return dummy.next
llist = Linked()
llist1 = Linked()
llist.push(6)
llist.push(4)
llist.push(3)
llist.push(2)
llist.push(1)
llist1.push(8)
llist1.push(6)
llist1.push(4)
llist1.push(2)
l = Linked()
print(l.intersect(llist,llist1).data)
Here is the traceback:
Traceback (most recent call last):
File "C:/Users/omsai/Desktop/intersection.py", line 48, in <module>
print(l.intersect(llist,llist1).data)
File "C:/Users/omsai/Desktop/intersection.py", line 26, in intersect
if l2.data>l1.data:
AttributeError: 'Linked' object has no attribute 'data'
You're calling Linked.intersect with two instances of Linked, which doesn't have a data member. You need to get the actual nodes out in the intersect method:
def intersect(self,l1,l2):
l1 = l1.head
l2 = l2.head
dummy = cur = Node(0)
# ...
You probably don't need to call intersect with two arguments; it would be enough to intersect one list against another:
def intersect(self, olinked):
thisone = self.head
otherone = olinked.head
retval = Linked()
while thisone and otherone:
if otherone.data > thisone.data:
thisone = thisone.next
elif thisone.data > otherone.data:
otherone = otherone.next
else: # thisone.data == otherone.data
retval.push(otherone.data)
thisone = thisone.next
otherone = otherone.next
return retval
# ...
llist.intersect(llist1).print_list()

Categories