I want to create a linked list and insert dummy data to verify it. Please see my code.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
a = ListNode(2)
a.next = ListNode(4)
a.next.next = ListNode(3)
print(a)
So I want to insert 2,4 and 3. Is the code right?
Why do you want to make a linked list? Python lists are pretty efficient and do all the things you normally do with a C type list and much more. Your example would be:
a = [2, 4, 3]
Start by writing a function that prints all the values in your linked list. Once you have that, you can use it for debugging.
Have the function create an empty list. Then append the node's value and see if there's a next node. When complete, print out the list.
I got an error
AttributeError: 'int' object has no attribute 'val'
.
I am a python beginner and could you please correct my code instead of comments.
Many thanks.
class ListNode:
def __init__(self, val = 0, next = None):
self.val = val
self.next = next
def listprint(self):
printval = self.val
while printval is not None:
print (printval.val)
printval = printval.next
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
integerL1 = ""
integerL2 = ""
curL1 = l1
curL2 = l2
while curL1 is not None or curL2 is not None:
if curL1 is not None:
integerL1 += str(curL1.val)
curL1 = curL1.next
if curL2 is not None:
integerL2 += str(curL2.val)
curL2 = curL2.next
integerL1 = integerL1[::-1]
integerL2 = integerL2[::-1]
integerL1 = int(integerL1)
integerL2 = int(integerL2)
combine = integerL1 + integerL2
combine = str(combine)
combine = combine[::-1]
main = l1
headOne = True
for i in range(len(combine)):
if headOne:
t = int(combine[i])
print(t)
l1 = ListNode(t)
print(l1.val)
main = l1
headOne = False
continue
if main.next is None:
p = int(combine[i])
main.next = ListNode(p)
main = main.next
return main
list1 = ListNode(2);
list1.next = ListNode(4)
list1.next.next = ListNode(3)
list2 = ListNode(5);
list2.next = ListNode(6)
list2.next.next = ListNode(4)
s = Solution()
merge = s.addTwoNumbers(list1, list2)
merge.listprint()
I used itertools zip to zip the lists together. To allow for uneven sized lists I used the zip_longest version. Because the LList naturally builds backwards I need to reverse the list when done so it is in the correct order (least significant digit is first).
For printing I added a __repr__ method to LList. I also added some convenience functions that are commonly provided by collection types.
import itertools
class LList:
def __init__(self, value=0, nxt=None):
self.value = value
self.nxt = nxt
def values(self):
"""Generator for getting all the values"""
ptr = self
while ptr:
yield ptr.value
ptr = ptr.nxt
def reverse(self):
"""Make new LList with order of values reversed"""
result = None
while self:
result = LList(self.value, result)
self = self.nxt
return result
def __len__(self):
"""Return number of values in LList"""
count = 0
ptr = self
while ptr is not None:
count += 1
ptr = ptr.nxt
return count
def __getitem__(self, index):
"""Get value by index: LList[index]"""
ptr = self
for _ in range(index):
ptr = ptr.nxt
return ptr.value
def __setitem__(self, index, value):
"""Set value by index: LList[index] = value"""
ptr = self
for _ in range(index):
ptr = ptr.nxt
ptr.value = value
def __repr__(self):
"""Return a pretty string representation of LList"""
return f'[{",".join([str(value) for value in self.values()])}]'
def LLNumber(value):
"""Make a LList from a number"""
if value > 10:
return LList(value % 10, LLNumber(value // 10))
return LList(value)
def LLAdd(a, b):
"""Add to LList numbers"""
carry = 0
result = None
for digits in itertools.zip_longest(a.values(), b.values(), fillvalue=0):
value = sum(digits)+carry
result = LList(value % 10, result)
carry = value // 10
if carry > 0:
result = LList(carry, result)
return result.reverse()
a = LLNumber(4321)
b = LLNumber(8765)
result = LLAdd(a, b)
print(a, '+', b, '=', result)
Output:
[1,2,3,4] + [5,6,7,8] = [6,8,0,3,1]
Thanks for your input. But I don't want a fancy solution. I just want to know what is wrong in my code so I can improve myself step as step. It is important for a beginner.
It would help to have the entire error message (especially including line numbers).
Your listprint() is a bit off...
def listprint(self):
printval = self.val
while printval is not None:
print (printval.val)
printval = printval.next
I believe
self
is supposed to be a node. So self.val (which you assign to
printval
) is an integer.
But then you ask for
printval.val
. That would be the same thing as
self.val.val
and isn't right.
I'm not sure why you're checking the
val if it's None. Normally I would expect every node to have a particular value, and the
.next
attribute might be None (but not the val).
Let's go back to the basic design.
ListNode is presumably a node within your list. It has properties of a value and a link to the next node (linked list). This is not the whole list.
Your listprint routine, by its name, is to print the whole list. You should NOT have that as a method of an individual node. Rather, if you want to print the value of an individual node, call the method nodeprint() and just print the value.
You could then create a function at the top level that runs the list and calls nodeprint() on each linked node.
Also, when you create a new node, you should update the next of the prior linked node at that time. Using next.next is going to get you into trouble.
Look at the below. There are still issues in how I create the linked list in that it is not generalizable.
linkedlist = []
class listnode:
def __init__(self,nvalue=0,nextnode=None,priornode=None):
self.val = nvalue
self.next = nextnode
self.prior = priornode
def printlist(thelist):
node = thelist[0]
while node.next != None :
print(node.val)
node = thelist[node.next]
#build a list
node1 = listnode(2)
linkedlist.append(node1)
node1 = listnode(5,None,0)
linkedlist[0].next = 1
linkedlist.append(node1)
node1 = listnode(4,None,1)
linkedlist[1].next = 2
linkedlist.append(nodel1)