HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Python Singly Linked List Implementation

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
singlypythonimplementationlistlinked

Problem

This is a follow-up to a question I asked a few days ago. I incorporated many of the suggestions on how to make the code more standardized and Python-like. If you see something else that can be improved, please let me know.

In addition, I also wrote unit tests. Could someone tell me how I am doing with those? Can I improve those somehow? Are they covering most use cases?

```
class LinkedList(object):
class Node(object):
"""
Inner class of LinkedList. Contains a blueprint for a node of the LinkedList
"""
def __init__(self, value, next=None):
"""
Initializes a List node with payload v and link n
"""
self.value=value
self.next=next

def __eq__(self,other):
"""
Defining comparison between nodes for unit testing
"""
if self.value == other.value and self.next == other.next:
return True
else:
return False

def __init__(self):
"""
Initializes a LinkedList and sets list head to None
"""
self.head=None
self.__current=self.head

def __len__(self):
"""
Returns the current size of the list. O(n), linear time
"""
current = self.head
count = 0
while current:
count += 1
current = current.next
return count

def __contains__(self,value):
"""
Returns True or False depending on whether an item with
node.value = value is in the list
"""
current = self.head
found = False
while current and not found:
if current.value == value:
found = True
return True
else:
current = current.next
if not current:
return False

def __bool__(self):
"""
Implements boolean check of the class
"""
if se

Solution

PEP8

While your code follows PEP8 principles there are few missing whitespaces around operators, this is a minor thing, but you should fix it.

Class Node

def __init__(self, value, next=None):
    """
    Initializes a List node with payload v and link n
    """
    self.value=value
    self.next=next


next is not the best name for a parameter since it shadows built-in function next consider using other name, e.g _next. Also, you have missing whitespaces around operator =

def __eq__(self,other):
    """
    Defining comparison between nodes for unit testing
    """
    if self.value == other.value and self.next == other.next:
        return True
    else:
        return False


Can be simplified to:

def __eq__(self,other):
    """
    Defining comparison between nodes for unit testing
    """
    return self.value == other.value and self.next == other.next:


Class LinkedList

def __contains__(self,value):
    """
    Returns True or False depending on whether an item with
    node.value = value is in the list
    """
    current = self.head
    found = False
    while current and not found:
        if current.value == value:
            found = True
            return True
        else:
            current = current.next
    if not current:
        return False


can be simplified to:

def __contains__(self,value):
    """
    Returns True or False depending on whether an item with
    node.value = value is in the list
    """
    current = self.head
    while current:
        if current.value == value:
            return True
        current = current.next
    return False


method __bool__:

def __bool__(self):
    """
    Implements boolean check of the class
    """
    if self.__len__() == 0:
        return False
    else:
        return True


In this particular case, you don't really have to define it, since if this method is not defined python will call __len__ and checks for a non-zero value, this is basically what your implementation does, so you might want to drop it.

method __next__:

You can actually get rid of this by moving logics to __iter__ and making it a generator. E.G:

def __iter__(self):
    while self.__current:
        current = self.__current
        self.__current = self.__current.next
        yield current

    self.__current=self.head


But if you want to keep your implementation then you don't need else part of statement

def __next__(self):
    """
    Provides the next entry to the iterator
    """
    if not self.__current:
        self.__current=self.head
        raise StopIteration
    current = self.__current
    self.__current=self.__current.next
    return current


method __str__:

rename variable toPrint, python does not use camelcase, but underscode, see PEP8

method search:

you can do pretty much same modification as in __contains__

Other improvements:

  1. You can store a length of your list in the object, so whenever you add/remove an item it will increase/decrease a counter. This will make your __len__ O(1) speed and will also improve speed of insert in case if position is out of borders of your list



  1. Think about defining a iterator for your object as a separate class, in your current implementation your list stores it's current position. So it might be possible that it will be changed in some other part of your code and your iteration might skip elements because of that.

Code Snippets

def __init__(self, value, next=None):
    """
    Initializes a List node with payload v and link n
    """
    self.value=value
    self.next=next
def __eq__(self,other):
    """
    Defining comparison between nodes for unit testing
    """
    if self.value == other.value and self.next == other.next:
        return True
    else:
        return False
def __eq__(self,other):
    """
    Defining comparison between nodes for unit testing
    """
    return self.value == other.value and self.next == other.next:
def __contains__(self,value):
    """
    Returns True or False depending on whether an item with
    node.value = value is in the list
    """
    current = self.head
    found = False
    while current and not found:
        if current.value == value:
            found = True
            return True
        else:
            current = current.next
    if not current:
        return False
def __contains__(self,value):
    """
    Returns True or False depending on whether an item with
    node.value = value is in the list
    """
    current = self.head
    while current:
        if current.value == value:
            return True
        current = current.next
    return False

Context

StackExchange Code Review Q#157085, answer score: 6

Revisions (0)

No revisions yet.