How I can remove all nodes that have a specific value?


#1

https://www.codecademy.com/paths/computer-science/tracks/cspath-linear-data-structures/modules/cspath-linked-lists/lessons/learn-linked-lists-python/exercises/linked-lists-python-list-iii

How I can check useful of this code, how I can remove all nodes that have a specific value??

# We'll be using our Node class
class Node:
  def __init__(self, value, next_node=None):
    self.value = value
    self.next_node = next_node
    
  def get_value(self):
    return self.value
  
  def get_next_node(self):
    return self.next_node
  
  def set_next_node(self, next_node):
    self.next_node = next_node

# Our LinkedList class
class LinkedList:
  def __init__(self, value=None):
    self.head_node = Node(value)
  
  def get_head_node(self):
    return self.head_node
  
  def insert_beginning(self, new_value):
    new_node = Node(new_value)
    new_node.set_next_node(self.head_node)
    self.head_node = new_node
    
  def stringify_list(self):
    string_list = ""
    current_node = self.head_node
    while current_node:
      string_list += str(current_node.value) + "\n"
      current_node = current_node.get_next_node()
    return string_list
  # Define your remove_node method below:
  def remove_node(self, value_to_remove):
    current_node = self.head_node
    if current_node.get_value() == value_to_remove:
      self.head_node = current_node.get_next_node()
    else:
      while current_node:
        next_node = current_node.get_next_node()
        if next_node.get_value() == value_to_remove:
          current_node.next_node = next_node.get_next_node()
          current_node = None
        else:
          current_node = next_node
chain1=LinkedList(5)
chain1.insert_beginning(8)
chain1.insert_beginning(9)
chain1.insert_beginning(10)
chain1.insert_beginning(10)
print(chain1.stringify_list())
chain1.remove_node(10)
print(chain1.stringify_list())

#2

You are going to have a temp node starting at your head.
Compare head to value_to_remove then check if temp.next.value is equal to the value to be removed. If so, point your current next at the node after the one to be removed (temp.next.next)
It helps to draw what you intend to do. Whiteboards help.

Let’s say our value to remove is 2

H---->1----->2---->3---->4---->5
^
tmp

Check if temp.next.value (1) is equal to 2
…nope advance temp to the next nod
temp = temp.next

H----1----->2---->3---->4---->5
     ^
   tmp

Check if temp.next.value (2) is equal to 2
Yep! time to remove it

temp.next = temp.next.next

H----1--------->3---->4---->5
     ^
   tmp

The reference to 2 is lost and your next node is what node 2 used to point at.

WIth python this is fine. 2 will be taken care of
In other languages you might ahve just lost that memory where 2 was and you’ll have to take a different approach

Imagine Tarzan, Before he lets go of a vine to swing he must first grab another vine, else he falls


#3

Yes but what if I Have next Node is also has value 2 how I can removes all Nodes with value 2 for example?

 def remove_node(self, value_to_remove):
    current_node = self.head_node
    if current_node.get_value() == value_to_remove:
      self.head_node = current_node.get_next_node()
    else:
      while current_node:
        next_node = current_node.get_next_node()
        if next_node.get_value() == value_to_remove:
          current_node.next_node = next_node.get_next_node()
          current_node = None
        else:
          current_node = next_node

when I call

chain1=LinkedList(5)
chain1.insert_beginning(8)
chain1.insert_beginning(9)
chain1.insert_beginning(10)
chain1.insert_beginning(10)
print(chain1.stringify_list())
chain1.remove_node(10)
print(chain1.stringify_list())

Output:
10
10
9
8
5

10
9
8
5


#4

Then we are talking about repeating the same statments
Loops

Think about our conditional if statement becoming a while


#5

I try use while loop in second part of if statement after else

def remove_node(self, value_to_remove):
    current_node = self.head_node
    if current_node.get_value() == value_to_remove:
      self.head_node = current_node.get_next_node()

but When head Node with appropriate value_to_remove finding and code not go any further else statement not use, how I can avoid it?

else:
      while current_node:
        next_node = current_node.get_next_node()
        if next_node.get_value() == value_to_remove:
          current_node.next_node = next_node.get_next_node()
          current_node = None
        else:
          current_node = next_node

can I use elif instead else?

  def remove_node1(self, value_to_remove):
    current_node = self.head_node
    while current_node:
      next_node = current_node.get_next_node()
      if current_node.get_value() == value_to_remove:
        self.head_node = current_node.get_next_node()
        next_node = current_node.get_next_node()
      elif next_node.get_value() == value_to_remove:
        current_node.next_node = next_node.get_next_node()
        current_node = None
      else:
        current_node = next_node
chain1=LinkedList(5)
chain1.insert_beginning(8)
chain1.insert_beginning(9)
chain1.insert_beginning(10)
chain1.insert_beginning(10)
chain1.insert_beginning(8)
print(chain1.stringify_list())
chain1.remove_node1(10)
print(chain1.stringify_list())

Unfortunately is not work.because elif statement checked from top to bottom what else I can do?
Output:
8
10
10
9
8
5

8
10
9
8
5


#6

I need you help please, I try built a method to remove all Nodes that have a specific value: remove_node1

class Node:
  def __init__(self, value, next_node=None):
    self.value = value
    self.next_node = next_node
    
  def get_value(self):
    return self.value
  
  def get_next_node(self):
    return self.next_node
  
  def set_next_node(self, next_node):
    self.next_node = next_node

class LinkedList:
  def __init__(self, value=None):
    self.head_node = Node(value)
  
  def get_head_node(self):
    return self.head_node
  
  def insert_beginning(self, new_value):
    new_node = Node(new_value)
    new_node.set_next_node(self.head_node)
    self.head_node = new_node
    
  def stringify_list(self):
    string_list = ""
    current_node = self.head_node
    while current_node:
      if current_node.value != None:
        string_list += str(current_node.value) + "\n"
      current_node = current_node.get_next_node()
    return string_list
def remove_node1(self, value_to_remove):
    current_node = self.head_node
    while current_node:
      next_node = current_node.get_next_node()
      if current_node.get_value() == value_to_remove:
        self.head_node = current_node.get_next_node()
        current_node.next_node = next_node
        current_node = None
      else:
        current_node = next_node
chain1=LinkedList(5)
chain1.insert_beginning(8)
chain1.insert_beginning(9)
chain1.insert_beginning(10)
chain1.insert_beginning(10)
chain1.insert_beginning(8)
print(chain1.stringify_list())
chain1.remove_node1(10)
print(chain1.stringify_list())

Outpute is
8
10
10
9
8
5

10
9
8
5
I try understand what is wrong because I lose my head.node whit value (8) and node with value (10) steal in chain.


Learn Python: Classes: Basta Fazoolin'
#7

I haven’t completed this module, so don’t have any ready answers for you. Have invited a member who may have more insight into the problem.


#8

Note that the LinkedList constructor for the lesson Linked Lists: Python creates a linked list with a single node, however repeated use of the remove_node method allows us to remove all nodes until the linked list is truly devoid of nodes. This discrepancy creates some awkwardness concerning what we should consider to be an empty linked list.

For the following, we will assume that an empty linked list contains no nodes at all - not even a head node …

  def remove_every(self, value_to_remove):
    """This method removes every node that contains the value value_to_remove"""
    if self.head_node == None:
      # Empty linked list; no work to do
      return
    # Remove all consecutive value_to_remove occurrences at the head
    while self.head_node.value == value_to_remove:
      # Remove the next node
      self.head_node = self.head_node.next_node
      if self.head_node == None:
        # linked list is now empty
        return 
    # Remove all additional occurrences of value_to_remove
    current_node = self.head_node
    while current_node.next_node != None:
      if current_node.next_node.value == value_to_remove:
        # Remove the next node
        current_node.next_node = current_node.next_node.next_node
      else:
        # Do not remove next node; simply advance to the next node
        current_node = current_node.next_node
    # reached end of linked list
    return

You may be able to refactor some of the code to simplify the above.