Movatterモバイル変換


[0]ホーム

URL:


— FREE Email Series —

🐍 Python Tricks 💌

Python Tricks Dictionary Merge

🔒 No spam. Unsubscribe any time.

Browse TopicsGuided Learning Paths
Basics Intermediate Advanced
apibest-practicescareercommunitydatabasesdata-sciencedata-structuresdata-vizdevopsdjangodockereditorsflaskfront-endgamedevguimachine-learningnumpyprojectspythontestingtoolsweb-devweb-scraping

Table of Contents

Recommended Video Course
Working With Linked Lists in Python

Linked Lists in Python: An Introduction

Linked Lists in Python: An Introduction

byPedro PregueiroReading time estimate 29mintermediatedata-structures

Table of Contents

Remove ads

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding:Working With Linked Lists in Python

Linked lists are like a lesser-known cousin oflists. They’re not as popular or as cool, and you might not even remember them from your algorithms class. But in the right context, they can really shine.

In this article, you’ll learn:

  • What linked lists are and when you should use them
  • How to usecollections.deque for all of your linked list needs
  • How to implement your own linked lists
  • What the other types of linked lists are and what they can be used for

If you’re looking to brush up on your coding skills for ajob interview, or if you want to learn more aboutPython data structures besides the usualdictionaries andlists, then you’ve come to the right place!

You can follow along with the examples in this tutorial by downloading the source code available at the link below:

Get the Source Code:Click here to get the source code you’ll use to learn about linked lists in this tutorial.

Understanding Linked Lists

Linked lists are an ordered collection of objects. So what makes them different from normal lists? Linked lists differ from lists in the way that they store elements in memory. While lists use a contiguous memory block to store references to their data, linked lists store references as part of their own elements.

Main Concepts

Before going more in depth on what linked lists are and how you can use them, you should first learn how they are structured. Each element of a linked list is called anode, and every node has two different fields:

  1. Data contains the value to be stored in the node.
  2. Next contains a reference to the next node on the list.

Here’s what a typical node looks like:

Example Node of a Linked List
Node

A linked list is a collection of nodes. The first node is called thehead, and it’s used as the starting point for any iteration through the list. The last node must have itsnext reference pointing toNone to determine the end of the list. Here’s how it looks:

Example Structure of a Linked List
Linked List

Now that you know how a linked list is structured, you’re ready to look at some practical use cases for it.

Practical Applications

Linked lists serve a variety of purposes in the real world. They can be used to implement (spoiler alert!) queues orstacks as well as graphs. They’re also useful for much more complex tasks, such as lifecycle management for an operating system application.

Queues or Stacks

Queues and stacks differ only in the way elements are retrieved. For a queue, you use aFirst-In/First-Out (FIFO) approach. That means that the first element inserted in the list is the first one to be retrieved:

Example Structure of a Queue
Queue

In the diagram above, you can see thefront andrear elements of the queue. When you append new elements to the queue, they’ll go to the rear end. When you retrieve elements, they’ll be taken from the front of the queue.

For a stack, you use aLast-In/First-Out (LIFO) approach, meaning that the last element inserted in the list is the first to be retrieved:

Example Structure of a Stack
Stack

In the above diagram you can see that the first element inserted on the stack (index0) is at the bottom, and the last element inserted is at the top. Since stacks use the LIFO approach, the last element inserted (at the top) will be the first to be retrieved.

Because of the way you insert and retrieve elements from the edges of queues and stacks, linked lists are one of the most convenient ways to implement these data structures. You’ll see examples of these implementations later in the article.

Graphs

Graphs can be used to show relationships between objects or to represent different types of networks. For example, a visual representation of a graph—say a directed acyclic graph (DAG)—might look like this:

Example Directed Graph
Directed Acyclic Graph

There are different ways to implement graphs like the above, but one of the most common is to use anadjacency list. An adjacency list is, in essence, a list of linked lists where each vertex of the graph is stored alongside a collection of connected vertices:

VertexLinked List of Vertices
12 → 3 → None
24 → None
3None
45 → 6 → None
56 → None
6None

In the table above, each vertex of your graph is listed in the left column. The right column contains a series of linked lists storing the other vertices connected with the corresponding vertex in the left column. This adjacency list could also be represented in code using adict:

Python
>>>graph={...1:[2,3,None],...2:[4,None],...3:[None],...4:[5,6,None],...5:[6,None],...6:[None]...}

The keys of this dictionary are the source vertices, and the value for each key is a list. This list is usually implemented as a linked list.

Note: In the above example you could avoid storing theNone values, but we’ve retained them here for clarity and consistency with later examples.

In terms of both speed and memory, implementing graphs using adjacency lists is very efficient in comparison with, for example, anadjacency matrix. That’s why linked lists are so useful for graph implementation.

Performance Comparison: Lists vs Linked Lists

In most programming languages, there are clear differences in the way linked lists and arrays are stored in memory. In Python, however, lists aredynamic arrays. That means that the memory usage of both lists and linked lists is very similar.

Further reading: Python’simplementation of dynamic arrays is quite interesting and definitely worth reading about. Make sure to have a look and use that knowledge to stand out at your next company party!

Since the difference in memory usage between lists and linked lists is so insignificant, it’s better if you focus on their performance differences when it comes totime complexity.

Insertion and Deletion of Elements

In Python, you can insert elements into a list using.insert() or.append(). For removing elements from a list, you can use their counterparts:.remove() and.pop().

The main difference between these methods is that you use.insert() and.remove() to insert or remove elements at a specific position in a list, but you use.append() and.pop() only to insert or remove elements at the end of a list.

Now, something you need to know about Python lists is that inserting or removing elements that arenot at the end of the list requires some element shifting in the background, making the operation more complex in terms of time spent. You can read the article mentioned above onhow lists are implemented in Python to better understand how the implementation of.insert(),.remove(),.append() and.pop() affects their performance.

With all this in mind, even though inserting elements at the end of a list using.append() or.insert() will have constant time,O(1), when you try inserting an element closer to or at the beginning of the list, the average time complexity will grow along with the size of the list:O(n).

Linked lists, on the other hand, are much more straightforward when it comes to insertion and deletion of elements at the beginning or end of a list, where their time complexity is always constant:O(1).

For this reason, linked lists have a performance advantage over normal lists when implementing a queue (FIFO), in which elements are continuously inserted and removed at the beginning of the list. But they perform similarly to a list when implementing a stack (LIFO), in which elements are inserted and removed at the end of the list.

Retrieval of Elements

When it comes to element lookup, lists perform much better than linked lists. When you know which element you want to access, lists can perform this operation inO(1) time. Trying to do the same with a linked list would takeO(n) because you need to traverse the whole list to find the element.

When searching for a specific element, however, both lists and linked lists perform very similarly, with a time complexity ofO(n). In both cases, you need to iterate through the entire list to find the element you’re looking for.

Introducingcollections.deque

In Python, there’s a specific object in thecollections module that you can use for linked lists calleddeque (pronounced “deck”), which stands fordouble-ended queue.

collections.deque uses an implementation of a linked list in which you can access, insert, or remove elements from the beginning or end of a list with constantO(1) performance.

How to Usecollections.deque

There are quite a fewmethods that come, by default, with adeque object. However, in this article you’ll only touch on a few of them, mostly for adding or removing elements.

First, you need to create a linked list. You can use the following piece of code to do that withdeque:

Python
>>>fromcollectionsimportdeque>>>deque()deque([])

The code above will create an empty linked list. If you want to populate it at creation, then you can give it aniterable as input:

Python
>>>deque(['a','b','c'])deque(['a', 'b', 'c'])>>>deque('abc')deque(['a', 'b', 'c'])>>>deque([{'data':'a'},{'data':'b'}])deque([{'data': 'a'}, {'data': 'b'}])

When initializing adeque object, you can pass any iterable as an input, such as a string (also an iterable) or a list of objects.

Now that you know how to create adeque object, you can interact with it by adding or removing elements. You can create anabcde linked list and add a new elementf like this:

Python
>>>llist=deque("abcde")>>>llistdeque(['a', 'b', 'c', 'd', 'e'])>>>llist.append("f")>>>llistdeque(['a', 'b', 'c', 'd', 'e', 'f'])>>>llist.pop()'f'>>>llistdeque(['a', 'b', 'c', 'd', 'e'])

Bothappend() andpop() add or remove elements from the right side of the linked list. However, you can also usedeque to quickly add or remove elements from the left side, orhead, of the list:

Python
>>>llist.appendleft("z")>>>llistdeque(['z', 'a', 'b', 'c', 'd', 'e'])>>>llist.popleft()'z'>>>llistdeque(['a', 'b', 'c', 'd', 'e'])

Adding or removing elements from both ends of the list is pretty straightforward using thedeque object. Now you’re ready to learn how to usecollections.deque to implement a queue or a stack.

How to Implement Queues and Stacks

As you learned above, the main difference between a queue and a stack is the way you retrieve elements from each. Next, you’ll find out how to usecollections.deque to implement both data structures.

Queues

With queues, you want to add values to a list (enqueue), and when the timing is right, you want to remove the element that has been on the list the longest (dequeue). For example, imagine a queue at a trendy and fully booked restaurant. If you were trying to implement a fair system for seating guests, then you’d start by creating a queue and adding people as they arrive:

Python
>>>fromcollectionsimportdeque>>>queue=deque()>>>queuedeque([])>>>queue.append("Mary")>>>queue.append("John")>>>queue.append("Susan")>>>queuedeque(['Mary', 'John', 'Susan'])

Now you have Mary, John, and Susan in the queue. Remember that since queues are FIFO, the first person who got into the queue should be the first to get out.

Now imagine some time goes by and a few tables become available. At this stage, you want to remove people from the queue in the correct order. This is how you would do that:

Python
>>>queue.popleft()'Mary'>>>queuedeque(['John', 'Susan'])>>>queue.popleft()'John'>>>queuedeque(['Susan'])

Every time you callpopleft(), you remove the head element from the linked list, mimicking a real-life queue.

Stacks

What if you wanted tocreate a stack instead? Well, the idea is more or less the same as with the queue. The only difference is that the stack uses the LIFO approach, meaning that the last element to be inserted in the stack should be the first to be removed.

Imagine you’re creating a web browser’s history functionality in which store every page a user visits so they can go back in time easily. Assume these are the actions a random user takes on their browser:

  1. VisitsReal Python’s website
  2. Navigates toPandas: How to Read and Write Files
  3. Clicks on a link forReading and Writing CSV Files in Python

If you’d like to map this behavior into a stack, then you could do something like this:

Python
>>>fromcollectionsimportdeque>>>history=deque()>>>history.appendleft("https://realpython.com/")>>>history.appendleft("https://realpython.com/pandas-read-write-files/")>>>history.appendleft("https://realpython.com/python-csv/")>>>historydeque(['https://realpython.com/python-csv/',       'https://realpython.com/pandas-read-write-files/',       'https://realpython.com/'])

In this example, you created an emptyhistory object, and every time the user visited a new site, you added it to yourhistory variable usingappendleft(). Doing so ensured that each new element was added to thehead of the linked list.

Now suppose that after the user read both articles, they wanted to go back to the Real Python home page to pick a new article to read. Knowing that you have a stack and want to remove elements using LIFO, you could do the following:

Python
>>>history.popleft()'https://realpython.com/python-csv/'>>>history.popleft()'https://realpython.com/pandas-read-write-files/'>>>historydeque(['https://realpython.com/'])

There you go! Usingpopleft(), you removed elements from thehead of the linked list until you reached the Real Python home page.

From the examples above, you can see how useful it can be to havecollections.deque in your toolbox, so make sure to use it the next time you have a queue- or stack-based challenge to solve.

Implementing Your Own Linked List

Now that you know how to usecollections.deque for handling linked lists, you might be wondering why you would ever implement your own linked list in Python. There are a few reasons to do it:

  1. Practicing your Python algorithm skills
  2. Learning about data structure theory
  3. Preparing for job interviews

Feel free to skip this next section if you’re not interested in any of the above, or if you already aced implementing your own linked list in Python. Otherwise, it’s time to implement some linked lists!

How to Create a Linked List

First things first, create aclass to represent your linked list:

Python
classLinkedList:def__init__(self):self.head=None

The only information you need to store for a linked list is where the list starts (thehead of the list). Next, create another class to represent each node of the linked list:

Python
classNode:def__init__(self,data):self.data=dataself.next=None

In the above class definition, you can see the two main elements of every single node:data andnext. You can also add a__repr__ to both classes to have a more helpful representation of the objects:

Python
classNode:def__init__(self,data):self.data=dataself.next=Nonedef__repr__(self):returnself.dataclassLinkedList:def__init__(self):self.head=Nonedef__repr__(self):node=self.headnodes=[]whilenodeisnotNone:nodes.append(node.data)node=node.nextnodes.append("None")return" -> ".join(nodes)

Have a look at an example of using the above classes to quickly create a linked list with three nodes:

Python
>>>llist=LinkedList()>>>llistNone>>>first_node=Node("a")>>>llist.head=first_node>>>llista -> None>>>second_node=Node("b")>>>third_node=Node("c")>>>first_node.next=second_node>>>second_node.next=third_node>>>llista -> b -> c -> None

By defining a node’sdata andnext values, you can create a linked list quite quickly. TheseLinkedList andNode classes are the starting points for our implementation. From now on, it’s all about increasing their functionality.

Here’s a slight change to the linked list’s__init__() that allows you to quickly create linked lists with some data:

Python
def__init__(self,nodes=None):self.head=NoneifnodesisnotNone:node=Node(data=nodes.pop(0))self.head=nodeforeleminnodes:node.next=Node(data=elem)node=node.next

With the above modification, creating linked lists to use in the examples below will be much faster.

How to Traverse a Linked List

One of the most common things you will do with a linked list is totraverse it. Traversing means going through every single node, starting with thehead of the linked list and ending on the node that has anext value ofNone.

Traversing is just a fancier way to say iterating. So, with that in mind, create an__iter__ to add the same behavior to linked lists that you would expect from a normal list:

Python
def__iter__(self):node=self.headwhilenodeisnotNone:yieldnodenode=node.next

The method above goes through the list andyields every single node. The most important thing to remember about this__iter__ is that you need to always validate that the currentnode is notNone. When that condition isTrue, it means you’ve reached the end of your linked list.

After yielding the current node, you want to move to the next node on the list. That’s why you addnode = node.next. Here’s an example of traversing a random list and printing each node:

Python
>>>llist=LinkedList(["a","b","c","d","e"])>>>llista -> b -> c -> d -> e -> None>>>fornodeinllist:...print(node)abcde

In other articles, you might see the traversing defined into a specific method calledtraverse(). However, using Python’sbuilt-in methods to achieve said behavior makes this linked list implementation a bit morePythonic.

How to Insert a New Node

There are different ways to insert new nodes into a linked list, each with its own implementation and level of complexity. That’s why you’ll see them split into specific methods for inserting at the beginning, end, or between nodes of a list.

Inserting at the Beginning

Inserting a new node at the beginning of a list is probably the most straightforward insertion since you don’t have to traverse the whole list to do it. It’s all about creating a new node and then pointing thehead of the list to it.

Have a look at the following implementation ofadd_first() for the classLinkedList:

Python
defadd_first(self,node):node.next=self.headself.head=node

In the above example, you’re settingself.head as thenext reference of the new node so that the new node points to the oldself.head. After that, you need to state that the newhead of the list is the inserted node.

Here’s how it behaves with a sample list:

Python
>>>llist=LinkedList()>>>llistNone>>>llist.add_first(Node("b"))>>>llistb -> None>>>llist.add_first(Node("a"))>>>llista -> b -> None

As you can see,add_first() always adds the node to thehead of the list, even if the list was empty before.

Inserting at the End

Inserting a new node at the end of the list forces you to traverse the whole linked list first and to add the new node when you reach the end. You can’t just append to the end as you would with a normal list because in a linked list you don’t know which node is last.

Here’s an example implementation of a function for inserting a node to the end of a linked list:

Python
defadd_last(self,node):ifself.headisNone:self.head=nodereturnforcurrent_nodeinself:passcurrent_node.next=node

First, you want to traverse the whole list until you reach the end (that is, until thefor loop raises aStopIteration exception). Next, you want to set thecurrent_node as the last node on the list. Finally, you want to add the new node as thenext value of thatcurrent_node.

Here’s an example ofadd_last() in action:

Python
>>>llist=LinkedList(["a","b","c","d"])>>>llista -> b -> c -> d -> None>>>llist.add_last(Node("e"))>>>llista -> b -> c -> d -> e -> None>>>llist.add_last(Node("f"))>>>llista -> b -> c -> d -> e -> f -> None

In the code above, you start by creating a list with four values (a,b,c, andd). Then, when you add new nodes usingadd_last(), you can see that the nodes are always appended to the end of the list.

Inserting Between Two Nodes

Inserting between two nodes adds yet another layer of complexity to the linked list’s already complex insertions because there are two different approaches that you can use:

  1. Insertingafter an existing node
  2. Insertingbefore an existing node

It might seem weird to split these into two methods, but linked lists behave differently than normal lists, and you need a different implementation for each case.

Here’s a method that adds a nodeafter an existing node with a specific data value:

Python
defadd_after(self,target_node_data,new_node):ifself.headisNone:raiseException("List is empty")fornodeinself:ifnode.data==target_node_data:new_node.next=node.nextnode.next=new_nodereturnraiseException("Node with data '%s' not found"%target_node_data)

In the above code, you’re traversing the linked list looking for the node with data indicating where you want to insert a new node. When you find the node you’re looking for, you’ll insert the new node immediately after it and rewire thenext reference to maintain the consistency of the list.

The only exceptions are if the list is empty, making it impossible to insert a new node after an existing node, or if the list does not contain the value you’re searching for. Here are a few examples of howadd_after() behaves:

Python
>>>llist=LinkedList()>>>llist.add_after("a",Node("b"))Exception: List is empty>>>llist=LinkedList(["a","b","c","d"])>>>llista -> b -> c -> d -> None>>>llist.add_after("c",Node("cc"))>>>llista -> b -> c -> cc -> d -> None>>>llist.add_after("f",Node("g"))Exception: Node with data 'f' not found

Trying to useadd_after() on an empty list results in anexception. The same happens when you try to add after a nonexistent node. Everything else works as expected.

Now, if you want to implementadd_before(), then it will look something like this:

Python
 1defadd_before(self,target_node_data,new_node): 2ifself.headisNone: 3raiseException("List is empty") 4 5ifself.head.data==target_node_data: 6returnself.add_first(new_node) 7 8prev_node=self.head 9fornodeinself:10ifnode.data==target_node_data:11prev_node.next=new_node12new_node.next=node13return14prev_node=node1516raiseException("Node with data '%s' not found"%target_node_data)

There are a few things to keep in mind while implementing the above. First, as withadd_after(), you want to make sure to raise an exception if the linked list is empty (line 2) or the node you’re looking for is not present (line 16).

Second, if you’re trying to add a new node before the head of the list (line 5), then you can reuseadd_first() because the node you’re inserting will be the newhead of the list.

Finally, for any other case (line 9), you should keep track of the last-checked node using theprev_node variable. Then, when you find the target node, you can use thatprev_node variable to rewire thenext values.

Once again, an example is worth a thousand words:

Python
>>>llist=LinkedList()>>>llist.add_before("a",Node("a"))Exception: List is empty>>>llist=LinkedList(["b","c"])>>>llistb -> c -> None>>>llist.add_before("b",Node("a"))>>>llista -> b -> c -> None>>>llist.add_before("b",Node("aa"))>>>llist.add_before("c",Node("bb"))>>>llista -> aa -> b -> bb -> c -> None>>>llist.add_before("n",Node("m"))Exception: Node with data 'n' not found

Withadd_before(), you now have all the methods you need to insert nodes anywhere you’d like in your list.

How to Remove a Node

To remove a node from a linked list, you first need to traverse the list until you find the node you want to remove. Once you find the target, you want to link its previous and next nodes. This re-linking is what removes the target node from the list.

That means you need to keep track of the previous node as you traverse the list. Have a look at an example implementation:

Python
 1defremove_node(self,target_node_data): 2ifself.headisNone: 3raiseException("List is empty") 4 5ifself.head.data==target_node_data: 6self.head=self.head.next 7return 8 9previous_node=self.head10fornodeinself:11ifnode.data==target_node_data:12previous_node.next=node.next13return14previous_node=node1516raiseException("Node with data '%s' not found"%target_node_data)

In the above code, you first check that your list is not empty (line 2). If it is, then you raise an exception. After that, you check if the node to be removed is the currenthead of the list (line 5). If it is, then you want the next node in the list to become the newhead.

If none of the above happens, then you start traversing the list looking for the node to be removed (line 10). If you find it, then you need to update its previous node to point to its next node, automatically removing the found node from the list. Finally, if you traverse the whole list without finding the node to be removed (line 16), then you raise an exception.

Notice how in the above code you useprevious_node to keep track of the, well, previous node. Doing so ensures that the whole process will be much more straightforward when you find the right node to be deleted.

Here’s an example using a list:

Python
>>>llist=LinkedList()>>>llist.remove_node("a")Exception: List is empty>>>llist=LinkedList(["a","b","c","d","e"])>>>llista -> b -> c -> d -> e -> None>>>llist.remove_node("a")>>>llistb -> c -> d -> e -> None>>>llist.remove_node("e")>>>llistb -> c -> d -> None>>>llist.remove_node("c")>>>llistb -> d -> None>>>llist.remove_node("a")Exception: Node with data 'a' not found

That’s it! You now know how to implement a linked list and all of the main methods for traversing, inserting, and removing nodes. If you feel comfortable with what you’ve learned and you’re craving more, then feel free to pick one of the challenges below:

  1. Create a method to retrieve an element from a specific position:get(i) or evenllist[i].
  2. Create a method to reverse the linked list:llist.reverse().
  3. Create aQueue() object inheriting this article’s linked list withenqueue() anddequeue() methods.

Apart from being great practice, doing some extra challenges on your own is an effective way to assimilate all the knowledge you’ve gained. If you want to get a head start by reusing all the source code from this article, then you can download everything you need at the link below:

Get the Source Code:Click here to get the source code you’ll use to learn about linked lists in this tutorial.

Using Advanced Linked Lists

Until now, you’ve been learning about a specific type of linked list calledsingly linked lists. But there are more types of linked lists that can be used for slightly different purposes.

How to Use Doubly Linked Lists

Doubly linked lists are different from singly linked lists in that they have two references:

  1. Theprevious field references the previous node.
  2. Thenext field references the next node.

The end result looks like this:

Example Node of a Doubly Linked List
Node (Doubly Linked List)

If you wanted to implement the above, then you could make some changes to your existingNode class in order to include aprevious field:

Python
classNode:def__init__(self,data):self.data=dataself.next=Noneself.previous=None

This kind of implementation would allow you to traverse a list in both directions instead of only traversing usingnext. You could usenext to go forward andprevious to go backward.

In terms of structure, this is how a doubly linked list would look:

Example Structure of a Doubly Linked List
Doubly Linked List

You learned earlier thatcollections.deque uses a linked list as part of its data structure. This is the kind oflinked list it uses. With doubly linked lists,deque is capable of inserting or deleting elements from both ends of a queue with constantO(1) performance.

How to Use Circular Linked Lists

Circular linked lists are a type of linked list in which the last node points back to thehead of the list instead of pointing toNone. This is what makes them circular. Circular linked lists have quite a few interesting use cases:

  • Going around each player’s turn in a multiplayer game
  • Managing the application life cycle of a given operating system
  • Implementing aFibonacci heap

This is what a circular linked list looks like:

Example Structure of a Circular Linked List
Circular Linked List

One of the advantages of circular linked lists is that you can traverse the whole list starting at any node. Since the last node points to thehead of the list, you need to make sure that you stop traversing when you reach the starting point. Otherwise, you’ll end up in an infinite loop.

In terms of implementation, circular linked lists are very similar to singly linked list. The only difference is that you can define the starting point when you traverse the list:

Python
classCircularLinkedList:def__init__(self):self.head=Nonedeftraverse(self,starting_point=None):ifstarting_pointisNone:starting_point=self.headnode=starting_pointwhilenodeisnotNoneand(node.next!=starting_point):yieldnodenode=node.nextyieldnodedefprint_list(self,starting_point=None):nodes=[]fornodeinself.traverse(starting_point):nodes.append(str(node))print(" -> ".join(nodes))

Traversing the list now receives an additional argument,starting_point, that is used to define the start and (because the list is circular) the end of the iteration process. Apart from that, much of the code is the same as what we had in ourLinkedList class.

To wrap up with a final example, have a look at how this new type of list behaves when you give it some data:

Python
>>>circular_llist=CircularLinkedList()>>>circular_llist.print_list()None>>>a=Node("a")>>>b=Node("b")>>>c=Node("c")>>>d=Node("d")>>>a.next=b>>>b.next=c>>>c.next=d>>>d.next=a>>>circular_llist.head=a>>>circular_llist.print_list()a -> b -> c -> d>>>circular_llist.print_list(b)b -> c -> d -> a>>>circular_llist.print_list(d)d -> a -> b -> c

There you have it! You’ll notice that you no longer have theNone while traversing the list. That’s because there is no specific end to a circular list. You can also see that choosing different starting nodes will render slightly different representations of the same list.

Conclusion

In this article, you learned quite a few things! The most important are:

  • What linked lists are and when you should use them
  • How to usecollections.deque to implement queues and stacks
  • How to implement your own linked list and node classes, plus relevant methods
  • What the other types of linked lists are and what they can be used for

If you want to learn more about linked lists, then check outVaidehi Joshi’s Medium post for a nice visual explanation. If you’re interested in a more in-depth guide, then theWikipedia article is quite thorough. Finally, if you’re curious about the reasoning behind the current implementation ofcollections.deque, then check outRaymond Hettinger’s thread.

You can download the source code used throughout this tutorial by clicking on the following link:

Get the Source Code:Click here to get the source code you’ll use to learn about linked lists in this tutorial.

Feel free to leave any questions or comments below. Happy Pythoning!

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding:Working With Linked Lists in Python

🐍 Python Tricks 💌

Get a short & sweetPython Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

AboutPedro Pregueiro

Hi! My name is Pedro and I'm a Python developer who loves coding, burgers and playing guitar.

» More about Pedro

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

MasterReal-World Python Skills With Unlimited Access to Real Python

Locked learning resources

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

MasterReal-World Python Skills
With Unlimited Access to Real Python

Locked learning resources

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

What Do You Think?

Rate this article:

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students.Get tips for asking good questions andget answers to common questions in our support portal.


Looking for a real-time conversation? Visit theReal Python Community Chat or join the next“Office Hours” Live Q&A Session. Happy Pythoning!

Keep Learning

Related Topics:intermediatedata-structures

Recommended Video Course:Working With Linked Lists in Python

Related Tutorials:

Keep reading Real Python by creating a free account or signing in:

Already have an account?Sign-In

Almost there! Complete this form and click the button below to gain instant access:

Documenting Python Code Guide

Linked Lists (Source Code)

🔒 No spam. We take your privacy seriously.


[8]ページ先頭

©2009-2025 Movatter.jp