Reputation: 31
my task is to remove the first occurring value from a linked list. The value is inputted by the user. Then, I also have to return a boolean value indicating whether the item was removed (True) or if the value is not in the linked list, return False. This is what I have so far.
def remove(lst, value):
lst.head = removeRec(lst.head, value)
def removeRec(node, value):
if isinstance(node, EmptyNode):
print("Cannot remove value from an empty list")
elif node.data == value:
return node.next
elif:
node.next = removeRec(node.next, value)
return node
else:
return False
The problem with this is that it doesn't return True if the item was removed. How would I implement that? Also, how would I implement a similar function iteratively. Thanks guys.
Upvotes: 0
Views: 3192
Reputation: 1
in case there is duplicate in the linkedlist
def removeLinkedList(node, value):
if not node:
return node
elif node.val == value:
return removeLinkedList(node.next,value)
else:
node.next = removeLinkedList(node.next, value)
return node
Upvotes: 0
Reputation: 434
I would do it like:
def remove(lst, value):
remove.ret = False
def removeRec(node, value):
if isinstance(node, EmptyNode):
print("Cannot remove value from an empty list")
elif node.data == value:
remove.ret = True
return node.next
else:
node.next = removeRec(node.next, value)
return node
lst.head = removeRec(lst.head, value)
return remove.ret
Upvotes: 0
Reputation: 104762
The "Pythonic" way to report that you've failed to achieve what you were asked to do is to raise an exception. This makes your code fairly simple:
def removeRec(node, value):
if isinstance(node, EmptyNode):
raise ValueError("Cannot remove value from an empty list")
elif node.data == value:
return node.next
else:
node.next = removeRec(node.next, value)
return node
This would work with your existing remove
function, leaving it to the caller to handle the exception in the calling code. However, if you wanted the remove
function to return a Boolean value indicating success or failure, you could catch the exception there:
def remove(lst, value):
try:
lst.head = removeRec(lst.head, value)
return True # only reached if no exception was raised by the recursion
except ValueError:
return False
If you're dead set against using exceptions for some reason (such as being in a class where they've not been taught yet), you could encode the failure of the removal in the return value from the recursive calls, but then you need to do extra checking for it, to avoid damaging your list:
def removeRec(node, value):
if isinstance(node, EmptyNode):
print("Cannot remove value from an empty list")
return None # your code did this implicitly, I'm being explicit
elif node.data == value:
return node.next
else:
rec_result = removeRec(node.next, value)
if rec_result is None:
return rec_result
else:
node.next = rec_result
return node
You then can do the same check from the recursive case in the non-recursive function, and turn the result value into a boolean:
def remove(lst, value):
rec_result = removeRec(lst.head, value)
if rec_result is None:
return False
else:
lst.head = rec_result
return True
Upvotes: 2
Reputation: 114038
you need to start with your base cases
now because of the nature of most lists you can treat the end value the same as if it was in the middle of the list
so really we have
as our base cases, now that you understand your base cases you can write your function
def removeRec(node,value):
if node.value == value: #only time this will happen is if the node is at the head
node.value = node.next.value
node.next = node.next.next
#you cannot simply say node= node.next since then it will not propagate to the actual list
return True # found and removed value
if node.next == None: #case where value is not in the list
return False #unable to remove
if node.next.value == value:
node.next = node.next.next
return True #successfully removed
return removeRec(node.next,value)#recursively continue searching
since nodes are mutable objects the list will just be updated ... it does not return a new list
Upvotes: 1