I want my code to print numbers from 0 to 5, instead it prints only 0 as output. Can anyone correct the code. code:
class Node:
def __init__(self, value):
self.value = value
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def display(self):
ptr = self.head
while ptr is not None:
print(ptr.value)
ptr = ptr.next
l1 = LinkedList()
ptr = l1
ptr.head = Node(0)
ptr.head.next = None
a = [1, 2, 3, 4, 5]
for i in a:
dummy = Node(i)
ptr.next = dummy
ptr = ptr.next
# Displaying the linked list
l1.display()
I tried to build a simple linked list in python and was trying to print the numbers that were stored in the linked list, but there is something wrong with my code and it isn't working as I wanted it to be.
You already have an answer, but I wanted to point out that you initialised ptr
as an instance of LinkedList
, but then in the loop deal with it as if it is an instance of Node
. But as ptr
is a LinkedList
, it does not have a next
attribute, and so the first iteration of the loop is actually adding a next
attribute to the ptr
object, and the rest of the values are chained to that.
Before the first iteration, we have:
l1 ptr
↓ ↓
┌─[LinkedList]─┐ ┌─[Node]─────┐
│ head: ──────────►│ value: 0 │
│ │ │ next: None │
└──────────────┘ └────────────┘
After the first iteration, we have accidentally created next
in the linked list instance:
l1
↓
┌─[LinkedList]─┐ ┌─[Node]─────┐
│ head: ──────────►│ value: 0 │
│ next: ─┐ │ │ next: None │
└────────│─────┘ └────────────┘
│ ┌─[Node]─────┐
└►│ value: 1 │
│ next: None │
└────────────┘
↑
ptr
And when all iterations have been done:
l1
↓
┌─[LinkedList]─┐ ┌─[Node]─────┐
│ head: ──────────►│ value: 0 │
│ next: ─┐ │ │ next: None │
└────────│─────┘ └────────────┘
│ ┌─[Node]───┐ ┌─[Node]───┐ ┌─[Node]───┐ ┌─[Node]───┐ ┌─[Node]─────┐
└►│ value: 1 │ │ value: 2 │ │ value: 3 │ │ value: 4 │ │ value: 5 │
│ next: ────►│ next: ────►│ next: ────►│ next: ────►│ next: None │
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └────────────┘
↑
ptr
But as the display
function will (correctly) start from head
and not from next
, it will only find the node with value 0.
Methods of your class should not have print
-- except while debugging. Instead of a display
method, it is better practice to define a method that returns a string, and leave it to the caller to print it. You could even define the __repr__
method for this, so that when the caller calls print
with a linked list as argument, this method will return the string for it.
And we can still improve. We could move the loop from display
into a method called __iter__
, so that a linked list is iterable. That feature can then be used for building the string in __repr__
, but also for other purposes.
Finally, it would be nice if the linked list constructor could already take the values for it as arguments, and insert these values immediately. In the loop that adds these values, you could also consider to do it backwards, while passing the next
link to the constructor as an extra argument. I find this quite elegant, as you don't have the need for a separate ptr
variable then.
So all that leads to this code:
class Node:
def __init__(self, value, nextnode=None): # Added parameter
self.value = value
self.next = nextnode
class LinkedList:
def __init__(self, *values): # Allow to immediately populate
self.head = None
for value in reversed(values):
self.insert(value)
def insert(self, value):
self.head = Node(value, self.head)
def __iter__(self):
ptr = self.head
while ptr:
yield ptr.value
ptr = ptr.next
def __repr__(self):
return " ".join(map(str, self)) # Relying on __iter__
l1 = LinkedList(1, 2, 3, 4, 5) # Pass values immediately
print(l1) # Relying on __repr__