How to Create a Stack in Python From Scratch: Step-By-Step — Codefather
--
In this tutorial we will create a stack in Python step-by-step. The stack is a LIFO (Last-in First-out) data structure.
To create a stack in Python you can use a class with a single attribute of type list. The elements of the stack are stored in the list using the push method and are retrieved using the pop method. Additional methods allow to get the size of the stack and the value of the element at the top of the stack.
We will build a custom class that implements the common operations provided by a stack data structure.
Let’s start building it!
How to Start Building the Class For the Stack
The data structure we will use inside our class to create a Python stack is a list.
The class will restrict the type of operations that can be performed against the list considering that a stack doesn’t allow all the operations that are possible with a Python list.
When working with a list you have the freedom to add and remove elements at the beginning in the middle and at the end of the list. The same doesn’t apply to a stack.
When working with a stack you can only add an element to the top of the stack and remove the element from the top of the stack. That’s because by definition a stack is a Last-in First-Out data structure.
Let’s start by creating a class called Stack that has a list attribute called elements.
The constructor of the stack class initialises the attribute elements to an empty list.
class Stack:
def __init__(self):
self.elements = []
The first two operations we want to support in our stack are push and pop:
- Push adds an element to the top of the stack.
- Pop removes the last element from the top of the stack.
Add two methods to our class to support the push and pop operations:
def push(self, data):
self.elements.append(data)
To push data to the top of the stack we use the list append method.
def pop(self):
return self.elements.pop()
To retrieve the last element from the top of the stack we use the list pop method.
Using the Push and Pop Operations on our Stack
Let’s test the class we have created so far.
class Stack:
def __init__(self):
self.elements = [] def push(self, data):
self.elements.append(data) def pop(self):
return self.elements.pop()
Create an instance of stack and use __dict__ to view the instance attributes.
stack = Stack()
print(stack.__dict__)[output]
{'elements': []}
As expected the only instance attribute is the empty list elements.
Then call the push method followed by the pop method.
stack.push(3)
stack.push('test')
print(stack.pop())
print(stack.pop())[output]
test
3
You can see that after calling the pop method twice we get back the two elements we have pushed to the top of the stack using the push operation.
Note: notice that the first element returned by pop() is the string “test” that is the second element we have pushed to the stack. That’s because of the LIFO nature of the stack.
Handling Errors When Using Pop on an Empty Stack
After calling the pop method twice in the previous section our stack is empty.
I wonder what happens if we call the pop operation again:
print(stack.pop())
We get back the following exception:
Traceback (most recent call last):
File "/opt/Python/Tutorials/create_stack.py", line 17, in
print(stack.pop())
File "/opt/Python/Tutorials/create_stack.py", line 9, in pop
return self.elements.pop()
IndexError: pop from empty list
This exception doesn’t fully make sense…
The reference to pop in the error message is correct but a list is mentioned in the error because our class uses a list as instance attribute.
This could be confusing for a user that would be using our class as a way to work with a stack and not with a list.
Let’s handle this error better…
We will check if the internal list is empty before trying to “pop” an element from it:
def pop(self):
if self.elements:
return self.elements.pop()
else:
return None
If the list is empty the pop operation performed against the stack object will return None.
stack = Stack()
print(stack.pop())
Confirm that the print statement above returns None.
Retrieve the Number of Elements in a Python Stack
At the moment we are not able to determine the number of elements in the stack.
Let’s add another method that returns the number of elements in the stack.
def size(self):
return len(self.elements)
The new method simply returns the length of the internal list elements using the len() function. Let’s test it…
stack = Stack()
stack.push(3)
stack.push('test')
print("Number of elements in the stack: {}".format(stack.size()))[output]
Number of elements in the stack: 2
Looks good :)
I would also like to be able to know if the stack is empty. Here is a new method that does that:
def empty(self):
return True if self.size() == 0 else False
This is an example of how you can call a class method from another method within the same class.
Notice how the empty() method calls the size() method.
Let’s test the new method:
stack = Stack()
print(stack.empty())
stack.push(3)
print(stack.empty())[output]
True
False
We are getting back the correct response from the empty() method.
Retrieve the Value of the Element at the Top of the Stack
Before completing this tutorial I would also like to implement a method that retrieves the value of the element at the top of the stack without removing it from the stack.
Considering that the internal attribute of the class is a list we can use an index to retrieve the last element.
The operation of retrieving the element at the top of the stack is called peek.
def peek(self):
return self.elements[-1]
This method is super simple. We are using a negative index to get the last element in the elements list that is basically the element at the top of our stack.
stack = Stack()
stack.push('cat')
stack.push(3)
stack.push(1.2)
print(stack.peek())[output]
1.2
The method does exactly what we wanted to do.
Conclusion
In this tutorial we have seen how to implement a stack in Python step-by-step using a custom class.
We have implemented five operations for our custom stack:
- Push: to add an element to the top of the stack.
- Pop: to retrieve the element at the top of the stack.
- Size: to get the size of the stack.
- Empty: to check if the stack is empty.
- Peek: to get the value of the element at the top of the stack.
I hope you found it useful :)
Originally published at https://codefather.tech on May 29, 2021.