Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set your subtitle preferences in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please refer to our video player troubleshooting guide for assistance.

Implementing Your Own Linked List

00:00 There are a few reasons why you might want to implement your own linked list in Python. For one, implementing linked lists is a great way to practice your Python algorithm and data structure skills.

00:13 Since we’re dealing with self-referential objects—aka nodes that point to other nodes—we have to be careful about the order in which we do things so we can avoid accidentally losing the entire list. After all, if we lose reference to one node, all the nodes that follow it are lost too. Linked lists are also very commonly asked about in technical interviews, so having hands-on experience working with them might just help you to land your next developer job, even if you never touch them again.

00:47 In languages that support object-oriented architectures—such as Python—linked lists are often implemented with objects called nodes that store references, or pointers, to other nodes.

01:01 Things work similarly in non-object-oriented languages like C, except there, you’d represent nodes with structs that are often dynamically allocated on the heap. Fortunately, this is a course on Python, so we won’t need to worry about allocating memory manually. The CPython interpreter will do that for us.

01:24 Before we start coding, let’s plan out what classes we’ll need to build. The first class is aptly called LinkedList. There will only ever be one LinkedList object in our program, and it will store an instance attribute called head that will point to a node object.

01:42 And of course, that node object will point to another, and another, and another—

01:49 until we have an entire linked list. Really, the LinkedList object is just a container that stores the head of our linked list in memory. Storing the linked list in this object has other benefits too, one of which being that we can create a method that will print out the contents of the internal linked list with little helpful arrows to show the links between nodes. In fact, we’ll create a bunch of methods to operate on the linked list. As for the Node class, that one is pretty small too. We’ll have two instance attributes, one for the data stored at this node, and another called next that points to the next node in the linked list.

02:34 Let’s head over to Visual Studio Code and try this out for ourselves.

02:39 I’m here in a new file called linked_lists.py, and the first thing I want to do is create the LinkedList and Node classes.

02:48 Nothing too special here—just two classes with some instance attributes. This is honestly all we need to get up and running with linked lists, but there’s one problem: this LinkedList type is not iterable, meaning that we can’t use it in a for loop to quickly print out its elements.

03:09 Instead, let’s override the default .__repr__() (dunder repr) method of both of these classes so that we can quickly get a string representation of them whenever we want.

03:20 This will allow us to see a visual representation of the nodes in the linked list, as well as the links between them. I’ll start with the Node class. To override the .__repr__() method, all we need to say is def __repr__(self):, and now we can just return the .data in this Node.

03:42 This means that whenever we try to print the value of a Node, it’ll print the items stored in the .data attribute. Things are a little more complex for the LinkedList class.

03:54 I’ll move down there and create that .__repr__() method. What we want to do here is traverse through the entire LinkedList one Node at a time, storing the .data item in each Node in a new Python list—that is, just a regular old list.

04:12 Then, we can use Python’s fancy .join() method to join the elements together, separating them with an arrow. To start, I’ll create a new variable called node that points to the .head of the internal LinkedList.

04:27 I’ll also need to create a list for the node data. We want to traverse as long as the current node is not None—that would indicate that we’re at the end of the list, so we should stop. Inside here, I’ll append the .data item of the current Node to our nodes collection. Then, so we don’t get stuck in an infinite loop, I’ll make sure to set the node variable equal to the next node in the linked list.

04:56 Once we’ve traversed the entire list, we should append None to the end to show that the last node points to no others.

05:06 Finally, I’ll return " -> ".join(nodes).

05:12 Let’s try out our new linked list in the interactive shell.

05:16 We can create a new linked list by instantiating the LinkedList class.

05:23 To test out our .__repr__() method, let’s inspect the value of this new list. As expected, we get None, because no nodes were traversed.

05:35 Now, let’s create a node called first_node, and that will equal a new Node object with a data value of "a". That right there is enough to be a linked list.

05:47 After all, linked lists can have only one node. All that’s left to do is point the .head of the llist object to the first_node object, and then we can inspect llist again.

06:02 And, as you can see, our Node is there. One thing to note is that we didn’t have to explicitly tell first_node to point to None for its .next attribute.

06:13 That’s because we never assign the .next attribute to anything, and so it just takes on the default value of None. We keep adding as many new nodes as we want.

06:25 Whichever one is never assigned the .next value will be treated as the last node in the linked list. I’ll create two new nodes called second_node and third_node. To create the links, do first_node.next = second_node

06:45 and second_node.next = third_node.

06:52 We’ve just manually built a linked list by setting each node to point to another one. If you’re following along then congratulations, because you’ve just implemented your very first linked list in Python. You’re well on your way to being able to implement more advanced data structures such as stacks, queues, and graphs. In the next video, we’ll make instantiating new LinkedList objects easier by adding a constructor.

Stan Taov on Oct. 7, 2020

Hi there,

I am a little bit confused here, how does node.data in LinkedList get its data to append to an empty list? If both classes are not inherited.

Austin Cepalia RP Team on Oct. 8, 2020

@Stan Taov Inheritance doesn’t come into play here, only composition. LinkedList is composed of a single Node object, referred to as the head. Each Node is composed of another Node object, or in the case that it is the last node in the list, None. This composition creates the links between all the nodes. Is that what you’re asking?

Bartosz Zaczyński RP Team on Oct. 8, 2020

The LinkedList class represents a container for the Node instances. Inheritance would only make sense if one of them were a subtype of the other. That’s not the case because neither list is a subtype of node nor is the latter a subtype of the former. In fact, the list is composed of nodes.

The node variable in the LinkedList class initially refers to the list’s head and is updated by the while loop. It’ll point to the next node on the list in each iteration until there are no more nodes.

Data is stored within the individual nodes, so there’s no direct access to it from the list. A list only knows about the nodes, so you need the .data attribute on the current node to access that data.

Stan Taov on Oct. 8, 2020

Hi Bartosz,

Thanks a lot for your reply, I need some clarification here (It’ll point to the next node on the list)can you please tell me how it gets to that list, I don’t see it. Data is located in each node. Node has only .head attribute, how it gets access to .data if we didn’t assign Node class to it?

Stan Taov on Oct. 8, 2020

Hi there,

I think I figured it out, we get the list from node since we assigned an object/instance first_node (Node class) to .head of LinkedList and can assess all its attributes.

Anurag Gupta on Dec. 21, 2021

I am confused as to how node = node.next will take us to next node? Is .next a built-in method or an attribute defined in Node class? How does this line work?

Bartosz Zaczyński RP Team on Jan. 3, 2022

@Anurag Gupta .next is a custom attribute of the Node class that holds the reference to the following node “linked” to it. The line of code you mentioned should be read from right to left. First, you take the current node and read the address of its immediate neighbor. Then, you reuse the same node variable in a loop by assigning the next node to it, so the current node becomes different on the next iteration.

Become a Member to join the conversation.