Reputation: 25
I'm trying to merge two linked lists in Python, but every time I receive the error: type object 'List' has no attribute 'merge' when it clearly has the function for merging.
Sample Input:
8 11 20 24 50
5 9 10 30 33 40 45
Sample Output:
5 8 9 10 11 20 24 30 33 40 45 50
class Node:
def __init__ (self, data):
self.data = data
self.next = None
class List:
def __init__(self):
self.head = None
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(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
For taking input:
inp = [int(i) for i in input().split(" ")]
inp2 = [int(i) for i in input().split(" ")]
l = List()
l2 = List()
for i in inp:
l.append(i)
for i in inp2:
l2.append(i)
rez = List.merge(l, l2)
print(rez)
Thank you for your time!
Upvotes: 1
Views: 109
Reputation: 45752
If you want your method to be callable on the class rather than on an object, you should make it static:
@staticmethod
def merge(head1, head2):
# etc...
You could also make your code a lot clearer (including to yourself) by using type hints as you are mixing up what is a List
and what is a Node
:
from typing import Any, Optional
class Node:
def __init__(self, data: Any):
self.data = data
self.next: Optional[Node] = None # might be Optional["Node"] since it inside it's own definition, I'm not sure check the mypy docs
class LinkedList:
def __init__(self, head: Optional[Node] = None):
self.head = head
def append(self, new_data: Any) -> None:
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
@staticmethod
def merge(list1: "LinkedList", list2: "LinkedList") -> "LinkedList":
if list1.head is None:
return list2
if list2.head is None:
return list1
if list1.head.data <= list2.head.data:
head = list1.head
list1 = LinkedList(list1.head.next)
else:
head = list2.head
list2 = LinkedList(list2.head.next)
temp = LinkedList(head)
temp.head.next = LinkedList.merge(list1, list2).head
return temp
test it with:
inp = [8, 11, 20, 24, 50]
inp2 = [5, 9, 10, 30, 33, 40, 45]
l = LinkedList()
l2 = LinkedList()
for i in inp:
l.append(i)
for i in inp2:
l2.append(i)
rez = LinkedList.merge(l, l2)
temp = rez.head
print(temp.data)
while temp.next:
temp = temp.next
print(temp.data)
Upvotes: 3
Reputation: 1952
You're getting yourself muddled with the heads and the list object types. You're calling it with lists sometimes and recursively calling it with heads, fixed it up for ya:
class Node:
def __init__ (self, data):
self.data = data
self.next = None
class List:
def __init__(self):
self.head = None
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(head1, head2):
list_given = type(head1) == List
if list_given:
head1 = head1.head
head2 = head2.head
temp = None
if head1 is None:
return head2
if head2 is None:
return head1
if head1.data <= head2.data:
temp = head1
temp.next = List.merge(head1.next, head2)
else:
temp = head2
temp.next = List.merge(head1, head2.next)
if list_given:
new_list = List()
new_list.head = temp
return new_list
else:
return temp
inp = [int(i) for i in input().split(" ")]
inp2 = [int(i) for i in input().split(" ")]
l = List()
l2 = List()
for i in inp:
l.append(i)
for i in inp2:
l2.append(i)
rez = List.merge(l, l2)
print(rez)
Upvotes: 1