Home > Mobile >  Filtering nodes in a DLL
Filtering nodes in a DLL

Time:03-19

Here is what I have so far, I want to create the function that would remove elements lower than a specified value in the doubly linked list or above the specified value.

class DoublyLinkedList:

    class Node:
        """ Nodes in list """

        def __init__(self, element, prev=None, next_node=None):
            self.element = element
            self.prev = prev
            self.next = next_node

    def __init__(self):
        self._header = self.Node(None, None, None)
        self._trailer = self.Node(None, None, None)
        self._header.next = self._trailer
        self._trailer.prev = self._header
        self._size = 0

    def append(self, element):

        :arg element: the value to add to this list
        
        new_node = self.Node(element, self._trailer.prev, self._trailer)
        self._trailer.prev.next = new_node
        self._trailer.prev = new_node
        self._size  = 1

    def __len__(self):
        return self._size

    def __str__(self):

        # Python's list is used here to avoid string concatenation
        result = []

        current = self._header.next
        for i in range(len(self)):
            result.append(current.element)
            current = current.next

        return str(result)

    def remove(self, low, high):
        for element in self:
            try:
    
            if element.next < low:
                element.next = element.next.next
        
            elif element.next > high:
                element.next = element.next.next
        
            except Exception as e:
                print('low must be less than or equal to high')
        
        pass  

^^ That is what I've tried so far ^^ here is how I wanted it to work: I'm not sure how to get it to filter out the higher or lower values

DoublyLinkedList.append(5)
DoublyLinkedList.append(7)
DoublyLinkedList.append(8)
DoublyLinkedList.append(3)
DoublyLinkedList.append(9)

[5, 7, 8, 3, 9]


DoublyLinkedList.remove(5,8)

its output should be:

[5, 7, 8]

CodePudding user response:

Some issues in your code:

  • append has a line that should be a comment (starting with #)
  • for element in self: will not work, as self is not iterable. Also, it is rarely a good idea to iterate over a collection with a for loop when you are planning to remove items from that same collection. It will be better to use a form of iteration that you have already used in the __str__ method.
  • element.next < low is comparing two different types: .next is a node, while low is a number. Calling that loop variable element is confusing, as that is also the name of the attribute of your nodes. You want to have something like current.next.element < low.
  • If the above is corrected, there is no reason why the try block should trigger an exception, let be that it has to do with how low and high relate to eachother. If you want to output a message when high > low, then don't do that in the loop, but just test for that condition before starting the loop.
  • When you remove one node, you should also decrease the list size.
  • You can avoid code repetition by using one if to compare with low and high in one expression, using operator chaining
  • DoublyLinkedList is the class, but a list should be an instance of that class. So you need to first create that instance, and then call the methods on that instance, not on the class.

Here is a correction of your code:

class DoublyLinkedList:

    class Node:
        """ Nodes in list """

        def __init__(self, element, prev=None, next_node=None):
            self.element = element
            self.prev = prev
            self.next = next_node

    def __init__(self):
        self._header = self.Node(None, None, None)
        self._trailer = self.Node(None, None, None)
        self._header.next = self._trailer
        self._trailer.prev = self._header
        self._size = 0

    def append(self, element):
        # :arg element: the value to add to this list
        new_node = self.Node(element, self._trailer.prev, self._trailer)
        self._trailer.prev.next = new_node
        self._trailer.prev = new_node
        self._size  = 1

    def __len__(self):
        return self._size

    def __str__(self):
        result = []
        current = self._header.next
        for i in range(len(self)):
            result.append(current.element)
            current = current.next
        return str(result)

    def remove(self, low, high):
        # Perform the check before the loop
        if low > high:
            print('low must be less than or equal to high')
            return
        # Iterate the nodes like in __str__, but start one node earlier
        current = self._header
        for i in range(len(self)):
            # Don't compare the node, but its element.
            # Use chained comparison;
            if low <= current.next.element <= high:
                # Only move to next node when not removing
                current = current.next
            else:
                current.next = current.next.next
                self._size -= 1  # Also reduce size

# Should create an instance and work with that
lst = DoublyLinkedList()
lst.append(5)
lst.append(7)
lst.append(8)
lst.append(3)
lst.append(9)
print(lst)  # [5, 7, 8, 3, 9]
lst.remove(5,8)
print(lst)  # [5, 7, 8]
  • Related