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]