What’s New ?

The Top 10 favtutor Features You Might Have Overlooked

Read More
Python

Python Linked List, Building a Chain of Nodes

Jul 03, 2026 11 Minutes Read Why Trust Us Why you can trust this guide. Written by working engineers and reviewed by our editorial team under a strict editorial policy for accuracy, clarity and zero bias. Kaustubh Saini By Kaustubh Saini Kaustubh Saini Kaustubh Saini
I'm Kaustubh Saini, founder of FavTutor. I have a genuine passion for coding and data science. In my articles, I aim to break down complex topics, share coding insights, and make learning more accessible. When I'm not writing, I'm always exploring ways to enhance your learning experience at FavTutor.
Connect on LinkedIn →
Python Linked List, Building a Chain of Nodes

You already know the Python list. You write scores = [10, 20, 30] and it just works. So why would anyone build a different kind of list by hand? Because in a job interview, someone will ask you to, and because building one teaches you how data structures actually work under the surface.

A linked list is a chain of small boxes, where each box holds a value and a link to the next box. There's no single block of memory like a normal list has. Instead the boxes sit anywhere, and each one points to where the next one lives. In this lesson you'll build the whole thing from scratch: one node, then a three-node chain by hand, then a small class that inserts, deletes, and searches.

What a linked list actually is

Picture a treasure hunt. Each clue tells you one thing plus where to find the next clue. The last clue says "you're done, there's nothing after this."

A linked list works the same way. Each box is called a node. A node holds two things: a value, and a link to the next node. That link is just a reference to another node. The last node's link points to None, and that None is how you know you've reached the end.

Three nodes in a row, each showing a value box and a next box, with arrows linking them and the last node pointing to None

The first node has a special name. It's the head. If you have the head, you can reach every other node by following the links one at a time. Lose the head and the whole chain is gone, because nothing else tells you where the list starts.

How it differs from a normal Python list

A Python list keeps all its items in one block of memory, side by side. Because they sit together in order, Python can jump straight to any position. Ask for scores[1] and you get it instantly, no matter how long the list is.

scores = [10, 20, 30]
print(scores[1])
scores.insert(0, 5)
print(scores)
# Output:
# 20
# [5, 10, 20, 30]

A linked list is different. Its nodes are scattered around memory, not lined up. There's no position number you can jump to. To reach the third node, you start at the head and follow two links. To reach the hundredth, you follow ninety-nine links. This is the trade you're making.

A Python list drawn as one solid block of boxes next to a linked list drawn as separate nodes joined by arrows

So a normal list is fast at reaching a position and slower when you add to the front (every item has to shift over). A linked list is slow at reaching a position and fast at adding to the front. Different jobs, different tool.

Why anyone uses one

Here's the one thing a linked list is genuinely good at. To add a new item at the very front, you make one new node, point it at the old head, and call it the new head. That's it. Nothing else moves.

In a normal Python list, inserting at the front means every existing item slides one spot to the right to make room. With three items that's nothing. With a million items, that's a million moves, every single time you insert at the front. The linked list changes one link instead.

The honest second reason is interviews. Linked lists are one of the most common data structure topics in coding interviews. Reversing a linked list, finding its middle, detecting a loop: these questions come up again and again. So even though you'll rarely build one at work, you learn it well because you'll be asked about it.

The Node class, three lines

A node needs to hold two things, so you build a small class for it. You haven't seen classes yet in this course, so here's the short version: a class bundles some data and functions together into one thing, and the __init__ method runs automatically when you create one, setting up its starting values. A later lesson covers classes properly. For now, just read it line by line.

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

Line one names the class Node. Line two says "when you make a new node, you hand it a value." Line three stores that value on the node as self.value. Line four sets self.next to None, because a brand new node isn't linked to anything yet. That's the whole node: a value and a link that starts empty.

Linking three nodes by hand

Before any helper class, let's build a chain the slow way so you can see the links. Make three nodes, then join them yourself:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

first = Node(10)
second = Node(20)
third = Node(30)

first.next = second
second.next = third

print(first.value)
print(first.next.value)
print(first.next.next.value)
print(first.next.next.next)
# Output:
# 10
# 20
# 30
# None

Read those last four prints slowly. first.value is 10. first.next is the second node, so first.next.value is 20. first.next.next is the third node, so its value is 30. And first.next.next.next is None, because you never gave the third node a next. That None is the end of the chain.

Walking the chain with a loop

Chaining .next.next.next by hand doesn't scale. To visit every node, you use a while loop with a pointer that walks forward. Start the pointer at the head, print the value, then move the pointer to the next node. Stop when the pointer reaches None.

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

first = Node(10)
first.next = Node(20)
first.next.next = Node(30)

node = first
while node is not None:
    print(node.value)
    node = node.next
# Output:
# 10
# 20
# 30
A pointer arrow moving across three linked nodes one step at a time until it reaches None

The line node = node.next is the heart of every linked list loop. It moves the pointer one step down the chain. Forget it and the loop never ends, because node stays on the same box forever. We'll come back to that mistake later.

A small LinkedList class

Doing this by hand every time is painful, so wrap it in a class. The LinkedList only needs to remember one thing: its head. Everything else it finds by walking. Here it is with three methods, add to front, add to end, and print.

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None

    def append(self, value):
        new_node = Node(value)
        if self.head is None:
            self.head = new_node
            return
        node = self.head
        while node.next is not None:
            node = node.next
        node.next = new_node

    def insert_at_front(self, value):
        new_node = Node(value)
        new_node.next = self.head
        self.head = new_node

    def display(self):
        node = self.head
        while node is not None:
            print(node.value, end=" -> ")
            node = node.next
        print("None")

chain = LinkedList()
chain.append(20)
chain.append(30)
chain.insert_at_front(10)
chain.display()
# Output:
# 10 -> 20 -> 30 -> None

Look at insert_at_front. It's three short lines and it never touches the rest of the chain. Make the node, point it at the current head, make it the new head. That's the cheap-insert advantage in code.

Insert at front shown in numbered steps: a new node is created, its link points to the old head, then the head label moves to the new node

The append method has more work to do. To add at the end, it walks all the way to the last node (the one whose next is None) and links the new node there. That walk is why adding to the end of a linked list is slower than adding to the front.

Deleting a node by value

Deleting is where people slip up, so go slowly. To remove a node, you don't erase it. You relink around it. Find the node just before the one you want gone, and point its next at the node after the target. The target now has nothing pointing to it, so Python cleans it up.

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None

    def append(self, value):
        new_node = Node(value)
        if self.head is None:
            self.head = new_node
            return
        node = self.head
        while node.next is not None:
            node = node.next
        node.next = new_node

    def delete(self, value):
        node = self.head
        if node is not None and node.value == value:
            self.head = node.next
            return
        while node is not None and node.next is not None:
            if node.next.value == value:
                node.next = node.next.next
                return
            node = node.next

    def display(self):
        node = self.head
        while node is not None:
            print(node.value, end=" -> ")
            node = node.next
        print("None")

chain = LinkedList()
chain.append(10)
chain.append(20)
chain.append(30)
chain.delete(20)
chain.display()
# Output:
# 10 -> 30 -> None
Deleting the middle node by pointing the first node's link past it straight to the third node

The first if handles a special case: what if the node you're deleting is the head itself? Then there's nothing before it, so you just move the head forward to the next node. The loop handles every other case by looking one step ahead with node.next.value.

Searching the chain

Searching is the same walk you already know, with a check inside. Start at the head, compare each value, and stop the moment you find a match.

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None

    def append(self, value):
        new_node = Node(value)
        if self.head is None:
            self.head = new_node
            return
        node = self.head
        while node.next is not None:
            node = node.next
        node.next = new_node

    def search(self, value):
        node = self.head
        while node is not None:
            if node.value == value:
                return True
            node = node.next
        return False

chain = LinkedList()
chain.append(10)
chain.append(20)
chain.append(30)
print(chain.search(20))
print(chain.search(99))
# Output:
# True
# False

The method returns a boolean: True as soon as it finds the value, False if the walk reaches None without a match. There's no shortcut here. You have to check nodes one by one, because a linked list can't jump to a position.

Singly and doubly linked lists

Everything above is a singly linked list: each node points forward only. You can walk from head to end, but never backward.

A doubly linked list gives each node a second link that points to the node before it. Now you can walk both directions, and deleting is easier because a node already knows who comes before it. The cost is more memory (two links per node instead of one) and more links to keep correct on every insert and delete. You won't write the full code here, just know the shape.

A singly linked node with one forward arrow next to a doubly linked node with a forward and a backward arrow

Linked list versus Python list

Here's the whole comparison in one place. Read it once and the trade-off sticks.

What you're doingPython listLinked list
Get the item at a positionInstant, jumps straight thereSlow, walks from the head
Add to the frontSlow, shifts every item overFast, changes one link
Add to the endFastSlow, walks to the last node
MemoryOne tidy blockExtra link stored per node
When to useAlmost alwaysInterviews, and heavy front inserts

For everyday Python, use a list. It's faster for the things you actually do, it's built in, and the code is shorter. You learn the linked list to pass interviews and to understand how structures work, not because you'll reach for one on a normal day. That's the honest answer, and anyone who tells you different is selling something.

Practice exercises

Try each one before you read the solution. Everything you need is above.

Build a three-node chain by hand

Make three nodes holding "Mon", "Tue", "Wed" and link them, then print all three values.

# Solution
class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

a = Node("Mon")
b = Node("Tue")
c = Node("Wed")
a.next = b
b.next = c

print(a.value, a.next.value, a.next.next.value)
# Output: Mon Tue Wed

Count the nodes

Given a three-node chain, count how many nodes it has by walking it.

# Solution
class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

head = Node(1)
head.next = Node(2)
head.next.next = Node(3)

count = 0
node = head
while node is not None:
    count += 1
    node = node.next
print(count)
# Output: 3

Insert at the front

Start with a chain of 20 then 30. Add 10 to the front so the chain reads 10, 20, 30.

# Solution
class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

head = Node(20)
head.next = Node(30)

new_node = Node(10)
new_node.next = head
head = new_node

node = head
while node is not None:
    print(node.value, end=" ")
    node = node.next
print()
# Output: 10 20 30

Find a value

Walk a chain of 5, 15, 25 and print True if 15 is in it.

# Solution
class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

head = Node(5)
head.next = Node(15)
head.next.next = Node(25)

target = 15
found = False
node = head
while node is not None:
    if node.value == target:
        found = True
        break
    node = node.next
print(found)
# Output: True

Common mistakes

  • Losing the head reference. If you move your loop pointer with self.head = self.head.next, you throw away the start of the list. Walk with a separate variable (node = self.head) and leave head alone.
  • Forgetting node = node.next in the loop. Without it the pointer never moves, so the while loop runs forever on the same node. This is the most common infinite loop with linked lists.
  • Not handling the empty list. If self.head is None, code that reads self.head.value crashes with an AttributeError. Check for the empty case first.
  • Relinking in the wrong order when deleting. If you overwrite a link before you've saved the node it pointed to, you cut off the rest of the chain. Point past the target first, then let the target go.

Frequently asked questions

What is a linked list in Python?

A chain of small objects called nodes. Each node holds a value and a link to the next node, and the last link is None. You build it yourself from a small Node class, because Python has no built-in linked list type.

Does Python have a built-in linked list?

No. You build your own with a Node class, or you use collections.deque, which is a doubly linked list under the surface and gives you fast adds and removes at both ends.

What's the difference between a linked list and a list?

A Python list stores items in one block and can jump to any position instantly. A linked list scatters its nodes and follows links, so it's slower to reach a position but faster to add at the front.

What is a node?

One box in the chain. It holds a value and a link (next) to the following node. In code it's a tiny class with two attributes.

What is the head of a linked list?

The first node. It's the only node you keep a direct reference to. From the head you can reach every other node by following links. Lose it and you lose the list.

Why does the last node point to None?

None marks the end. When your walking pointer reaches None, there are no more nodes, so your loop knows to stop.

When should I use a linked list?

Rarely in everyday Python, a list is better for most work. Use one to answer interview questions, or when your program does a lot of inserting and removing at the front and you want that to stay fast.

What's the difference between singly and doubly linked?

A singly linked node points forward only. A doubly linked node also points backward, so you can walk both ways and delete more easily, at the cost of extra memory and more links to maintain.

Key takeaways

  • A linked list is a chain of nodes, where each node holds a value and a link to the next one, and None marks the end.
  • The head is the first node and your only handle on the list. Walk the chain with node = node.next until you hit None.
  • Adding to the front is one link change, which is the real advantage. Reaching a position means walking from the head, which is the real cost.
  • A Node class needs just a value and a next. A LinkedList class needs just a head, plus methods to insert, delete, and search.
  • In day-to-day Python you'll almost always use a normal list. You learn linked lists for interviews and to understand how data structures work.

The most common place a linked list shows up in real Python is hidden inside collections.deque, which powers fast stacks and queues. If you want to see that in action instead of building the links yourself, read our guide to stacks and queues in Python.

Kaustubh Saini
About the author

Kaustubh Saini

I'm Kaustubh Saini, founder of FavTutor. I have a genuine passion for coding and data science. In my articles, I aim to break down complex topics, share coding insights, and make learning more accessible. When I'm not writing, I'm always exploring ways to enhance your learning experience at FavTutor. Connect on LinkedIn →