Implementing a Linked List in Python: Easy as 1,2,3.

Search for a command to run...

No comments yet. Be the first to comment.
A guide to building a production-ready API with modular architecture, database integration using Prisma, automated API docs with Swagger & Docker.

We all come across chatbots when visiting various sites, while some of them operate behind real-human interaction, others are powered by AI. In this article, we'll walk through building a simple AI-powered chatbot using TensorFlow and JavaScript. The...

Running localhost on your mobile phone can be a valuable tool for developers and tech enthusiasts alike. With localhost, you can test and run applications and websites on your mobile device, without the need for an external server. This of course is ...

Trying to download a base64 PDF/File from an API request with one click?

An explanation of the debounce function and how to use it in your React Application

If you are learning data structures, a Linked List is one of the data structures you should know, albeit not so common, linked lists are similar to Lists (or arrays); you probably never heard or used them until now, but in the right context they prove to be useful.
In this article, you will learn:
A linked list is a sequence of data elements, which are connected together via links. Each element (node) in a linked list contains a connection to another data element in form of a pointer.
That every element in a linked list is called a Node, and every node contains a data (value to be stored) and next (reference to the next node) fields.

A linked list therefore is a collection of nodes, with the last node pointing to None

In a linked list, the time complexity for the operations is given as:
Space complexity however is O(n).
There are 3 main types of linked lists;


This comes in 2 parts, creating our list Node, and the Linked List itself. So, first thing first, create a class to represent each Node of the linked list
class Node:
def __init__(self, data):
self.data = data
self.next = None
As you can see each node contains just 2 fields, the data, and next.
Next, create a class to represent your linked list :
class LinkedList:
def __init__(self, nodes=None):
self.head = None
if nodes is not None:
node = Node(data=nodes.pop(0))
self.head = node
for n in nodes:
node.next = Node(data=n)
node = node.next
Let's update each of our classes with a repr function so our new code looks like this :
class Node:
def __init__(self, data):
self.data = data
self.next = None
def __repr__(self):
return self.data
class LinkedList:
def __init__(self, nodes=None):
self.head = None
if nodes is not None:
node = Node(data=nodes.pop(0))
self.head = node
for n in nodes:
node.next = Node(data=n)
node = node.next
def __repr__(self):
node = self.head
nodes = []
while node is not None:
nodes.append(node.data)
node = node.next
nodes.append("None")
return " -> ".join(nodes)
The code above would rightly allow us to create a linked list, notice that in the LinkedList init function if the node is not passed we initialized it to None.
my_list = LinkedList()
firstNode = Node("1")
my_list.head = firstNode
secondNode = Node("2")
firstNode.next = secondNode
print(my_list)
>>> 1 -> 2 -> None
To help us use our linked lists even more efficiently, we would implement some methods to:
Traversing a linked list means iterating through the list, and we add the iter function to allow us to replicate the same behavior from regular lists (arrays)
def __iter__(self):
node = self.head
while node is not None:
yield node
node = node.next
The code above goes through the list if it does not equal to None and yields every node before re-assigning the node to the next node if it exists.
def add_at_beginning(self, node):
node.next = self.head
self.head = node
In the above code, you're setting the next value to the present head value before re-assigning head to the new node
def add_at_end(self, node):
if self.head is None:
self.head = node
return
for current in self:
pass
current.next = node
While inserting at the end is similar to inserting at the beginning, first, you want to traverse the whole list until you reach the end. Next, you want to set current as the last node on the list. Finally, you want to add the new node as the next value of that current.
class Node:
def __init__(self, data):
self.data = data
self.next = None
def __repr__(self):
return self.data
class LinkedList:
def __init__(self, nodes=None):
self.head = None
if nodes is not None:
node = Node(data=nodes.pop(0))
self.head = node
for elem in nodes:
node.next = Node(data=elem)
node = node.next
def __repr__(self):
node = self.head
nodes = []
while node is not None:
nodes.append(node.data)
node = node.next
nodes.append("None")
return " -> ".join(nodes)
# Traverse a Linked List
def __iter__(self):
node = self.head
while node is not None:
yield node
node = node.next
# Insert a new node at the beginning
def add_at_beginning(self, node):
node.next = self.head
self.head = node
# Insert a new node at the end
def add_at_end(self, node):
if self.head is None:
self.head = node
return
for current_node in self:
pass
current_node.next = node
To wrap up a final example, have a look at how it works:
my_list = LinkedList()
firstNode = Node("1")
secondNode = Node("2")
my_list .head = firstNode
firstNode.next = secondNode
my_list.add_at_beginning(Node("3"))
my_list.add_at_end(Node("4"))
print(my_list)
>>> 3 -> 1 -> 2 -> 4 -> None
In this article, you learned quite a few things, The most important are:
I hope you enjoyed reading it as much as I enjoyed writing it :)