Stack in Python: How to Build a Python Stack Data Structure
What is a stack in Python?
In computer science, a stack is a linear data structure represented by a collection of items that utilizes a last-in-first-out (LIFO) model for access.
There are two operations that are fundamental to this data structure:
- A
.push()function that adds an item to the stack. - A
.pop()function that removes the most recently added item to the stack.
This type of collection is analogous to a stack of items, such as dinner plates, where the topmost item must be removed to access the items underneath. Stacks are useful in implementing actions such as a depth-first search. This article will explore the process of implementing a stack in Python.
Blueprint for implementing a stack in Python
Before we begin, we need to decide what kind of capabilities we want in our stack implementation. The .push() and .pop() functions fulfill the minimum requirements. But we also might want the following:
- Python’s
len()function to let us know how many items are in the stack, and to warn us when the stack is empty. It’s good practice to check for an empty stack when using one in a program. - A
.peek()function to tell us the value of the top item on the stack without removing it.
Lastly, we want to decide how the .peek() or .pop() methods behave when they are called on an empty stack. We could return something like NaN, but that might lead to subtle errors down the line, especially if a NaN value is added to the stack. A better practice in this scenario is to raise an exception when we try to use these functions on an empty stack. That way, such an event can get caught during testing, and the code using the stack can be updated appropriately.
Building the stack class
Our stack is going to be a Python class. Once we declare our class, the first thing we want to add is a container to hold the items in our stack. To do this, we create an internal variable:
class stack:def __init__(self):self.__index = []
Upon initialization of our stack class, it will initialize the __index variable as an empty list. This list will hold the items in our stack.
Setting up the len() function
We’ll first set up the len() function for our class, since we’ll want to check it before using our .pop() and .peek() methods. We’ll do this by implementing a “magic” method, also called a Dunder (double-underscore) method. Dunder methods allow us to override the behavior of built-in Python operations. For our stack, we can leverage the len() Dunder method to institute the “length” behavior we need:
class stack:def __init__(self):self.__index = []def __len__(self):return len(self.__index)
Now, when we call len(stack_instance), it will return the number of items in our __index variable.
>>> s = stack()>>> # some additional stack operations go here>>> len(s) # fetch number of items in the stack2
Setting up the .push() method
Next, we want to set up our .push() method that will place items in our __index variable. Since __index is a list, our main decision will be at which “end” of the list we should insert our items.
The first impulse might be to append items to our __index list, since we usually think of the highest-indexed item to be the “top”. However, this approach can be problematic for our purposes. This is because our reference, the “top” index, will always be changing as we perform operations on our stack. Additionally, this value would need to be recalculated every time we referenced it.
It is more efficient to add and remove items from the “beginning” of our list, since the index of the “beginning” never changes. It will always be zero. Therefore, our __index variable will be ordered with the “top” item as the first item of our list. Since we are working with a Python list, this can be done with the built-in .insert() method:
class stack:def __init__(self):self.__index = []def __len__(self):return len(self.__index)def push(self,item):self.__index.insert(0,item)
Setting up the .peek() method
The .peek() method is pretty straightforward. It returns the “top” value of the stack, which refers to the first item in our list, __index[0]. However, we need to take into account the possibility that our list is empty. We will want to check our stack with the len() function and throw an exception if we’re trying to use .peek() on an empty stack:
class stack:def __init__(self):self.__index = []def __len__(self):return len(self.__index)def push(self,item):self.__index.insert(0,item)def peek(self):if len(self) == 0:raise Exception("peek() called on empty stack.")return self.__index[0]
Setting up the .pop() method
The .pop() method is exactly the same as the .peek() method, with the further step of removing the returned item from the stack. Like .peek(), we’ll want to check for an empty list before trying to return a value:
class stack:def __init__(self):self.__index = []def __len__(self):return len(self.__index)def push(self,item):self.__index.insert(0,item)def peek(self):if len(self) == 0:raise Exception("peek() called on empty stack.")return self.__index[0]def pop(self):if len(self) == 0:raise Exception("pop() called on empty stack.")return self.__index.pop(0)
It’s important to note that a Python list has its own .pop() method, which behaves almost the same as our stack .pop() method, except that the list version can take an index and “pop” an item from anywhere in the list.
Setting up the str() function
An additional thing we can do is tell Python how we want our stack printed with the str() function. At the moment, using it yields the following results:
>>> s = stack()>>> print(str(s))'<__main__.stack object at 0x000002296C8ED160>'
In order to understand the contents of our stack, we’ll want something a little more useful. This is where the __str__() Dunder method comes in handy:
class stack:def __init__(self):self.__index = []def __len__(self):return len(self.__index)def push(self,item):self.__index.insert(0,item)def peek(self):if len(self) == 0:raise Exception("peek() called on empty stack.")return self.__index[0]def pop(self):if len(self) == 0:raise Exception("pop() called on empty stack.")return self.__index.pop(0)def __str__(self):return str(self.__index)
This will return the contents of our stack, just like printing out the items of a generic list.
Using the stack class
We now have a usable stack class. The code below highlights all of the functionality we’ve implemented in our custom class:
>>> s = stack()>>> s.peek() # stack = []Exception: peek() called on empty stack.>>> len(s)0>>> s.push(5) # stack = [5]>>> s.peek()5>>> s.push('Apple') # stack = ['Apple',5]>>> s.push({'A':'B'}) # stack = [{'A':'B'},'Apple',5]>>> s.push(25) # stack = [25,{'A':'B'},'Apple',5]>>> len(s)4>>> str(s)"[25, {'A': 'B'}, 'Apple', 5]">>> s.pop() # stack = [{'A':'B'},'Apple',5]25>>> s.pop() # stack = ['Apple',5]{'A': 'B'}>>> str(s)"['Apple', 5]">>> len(s)2
Conclusion
In this article, we built a stack in Python from scratch. We learned how stacks operate using the LIFO (Last-In, First-Out) principle and how to implement our own stack using Python lists. We walked through the creation of a custom stack class, added methods for pushing, popping, peeking, and checking the length, and made the stack printable for easier debugging.
By understanding and building a stack ourselves, we’re now better equipped to grasp how memory and control flow work in recursion, backtracking algorithms, and expression evaluation.
If you want to learn more about stacks in Python, check out the Linear Data Structures course on Codecademy.
Frequently asked questions
1. Why is stack used?
A stack is used to store and manage data in a Last-In-First-Out (LIFO) order. This is useful when the most recent item added needs to be accessed or removed first, such as in undo operations, function call management, and syntax parsing.
2. When to use stack?
Use a stack when:
- You need to reverse data (e.g., reversing strings).
- You want to track function calls (like recursion).
- Implementing features like undo/redo, expression evaluation, or parsing nested structures (e.g., parentheses).
- Managing browser history or backtracking in algorithms.
3. What are the features of stack?
Key features of a stack include:
- LIFO behavior (Last-In, First-Out)
- Two main operations:
.push()(to add an item) and.pop()(to remove the top item) - Often includes
.peek()or.top()to view the top element without removing it. - Can be implemented using lists, deque, or custom classes in Python.
4. What are the applications of stack in Python?
Some real-world applications of stack in Python include:
- Function call tracking in recursion
- Expression evaluation (e.g., postfix, infix to postfix conversion)
- Backtracking (e.g., in mazes or puzzles)
- Syntax checking in compilers
- Undo mechanisms in editors or games
5. What are the advantages and disadvantages of stack?
Advantages of a stack:
- Simple and easy to implement
- Efficient for LIFO operations
- Useful for memory management and parsing tasks
Disadvantages of a stack:
- Limited access; only the topmost element can be accessed directly
- May lead to stack overflow if not handled properly in recursive calls
- Not suitable for random access or complex data retrieval
'The Codecademy Team, composed of experienced educators and tech experts, is dedicated to making tech skills accessible to all. We empower learners worldwide with expert-reviewed content that develops and enhances the technical skills needed to advance and succeed in their careers.'
Meet the full teamRelated articles
- Article
Python Stack Data Structure: When and Why to Use it
Learn when and why to use stacks in Python. Understand LIFO, explore real use cases, compare stack implementation methods, and choose between lists, stacks, and queues. - Article
Data Structure APIs
A brief overview of APIs as they relate to JavaScript data structures. - Article
A Guide to Python Data Structures
Learn the fundamentals of Python data structures in this comprehensive guide, covering different types, examples, and ideal scenarios for using them efficiently.
Learn more on Codecademy
- Learn about virtualization of computer memory by building the fundamental data structures of computer science: lists, stacks, and queues.
- With Certificate
- Intermediate.4 hours
- Learn how to leverage the power of double-ended queues (deques) in Python.
- Advanced.< 1 hour
- Learn the basics of the world's fastest growing and most popular programming language used by software engineers, analysts, data scientists, and machine learning engineers alike.
- Beginner Friendly.17 hours
- What is a stack in Python?
- Blueprint for implementing a stack in Python
- Building the `stack` class
- Setting up the `len()` function
- Setting up the `.push()` method
- Setting up the `.peek()` method
- Setting up the `.pop()` method
- Setting up the `str()` function
- Using the `stack` class
- Conclusion
- Frequently asked questions