A Complete Guide to Stacks in Python

A stack in Python is an abstract data type that stores the order in which items were added to the structure but only allows additions/deletions to the top of the stack.

Written by Dhananjay Patel
Published on Apr. 09, 2025
Developer coding in python
Image: Shutterstock / Built In
Brand Studio Logo

A stack is a linear data structure that follows the last in, first out (LIFO) principle. This means that the last element added to the stack is the first one to be removed. Stacks are widely used in programming for tasks such as expression evaluation, backtracking, function call management and undo/redo functionality in applications.

Stacks can be implemented in multiple ways, and Python provides different built-in data structures to implement stacks efficiently. In this guide, we will explore different stack implementations in Python, their advantages and their limitations.

Stacks in Python Defined

A stack in Python is a linear data structure that follows the last in, first out principle, which means the last element added to a stack is the first removed. It’s used for tasks like backtracking, undo/redo functionality, expression evaluation and function calls.

 

Stack in Python Functions to Know

To work with stacks in Python, you should be familiar with the following functions:

  • push(): Adds an element to the stack. It is equivalent to the append() function in lists or put() in queue.LifoQueue.
  • pop(): Removes and returns the top element of the stack. If the stack is empty, it may raise an error.
  • peek(): Returns the top element without removing it from the stack. This helps in checking the last added element without modifying the stack.
  • isEmpty(): Checks if the stack is empty and returns True if there are no elements, otherwise False.
  • size(): Returns the number of elements currently stored in the stack.

These functions help in efficiently managing and manipulating stack data structures in Python.

More on Pandas6 Ways to Convert a List to Pandas DataFrame

 

How to Implement Stacks in Python

Python provides multiple ways to implement stacks, including lists, collections.deque and the queue module.

Using List

Python lists can be used as stacks with append() and pop(), but they have performance limitations due to dynamic resizing and inefficient memory handling.

class Stack:
    def __init__(self):
        self.stack = []

    def push(self, item):
        self.stack.append(item)

    def pop(self):
        if not self.is_empty():
            return self.stack.pop()
        return "Stack is empty"

    def peek(self):
        return self.stack[-1] if not self.is_empty() else "Stack is empty"

    def is_empty(self):
        return len(self.stack) == 0

    def size(self):
        return len(self.stack)

Lists are simple to use but may have performance issues when the stack grows significantly, as resizing operations take additional time.

Using collections.deque

Deque (double-ended queue) provides an efficient stack implementation with O(1) time complexity for both append() and pop() operations, making it more efficient than lists for stack operations.

from collections import deque

stack = deque()
stack.append(1)
stack.append(2)
stack.append(3)
print(stack.pop())  # Output: 3

# Additional deque functions
stack.appendleft(0)  # Adds element to the left end
stack.popleft()  # Removes element from the left end
print(stack)  # Shows remaining elements in stack

# Checking stack properties
print(len(stack))  # Returns stack size
print(stack[-1])  # Peeks at the last element without removing it

deque is recommended for most stack implementations as it is optimized for fast insertions and deletions.

Using queue.LifoQueue

The queue module provides a thread-safe stack implementation using LifoQueue, making it ideal for multi-threaded environments.

from queue import LifoQueue

stack = LifoQueue()
stack.put(1)
stack.put(2)
stack.put(3)
print(stack.get())  # Output: 3

# Additional LifoQueue functions
print(stack.qsize())  # Returns the current size of the stack
print(stack.empty())  # Checks if the stack is empty
stack.put(4)
print(stack.queue)  # Accessing all elements in the queue

This implementation is particularly useful when working with multi-threaded programs where thread safety is essential.

 

Advantages of Stack in Python

  • Easy to implement: Stacks can be implemented easily using Python lists or deque.
  • Efficient for specific operations: Operations like undo/redo, function calls, and backtracking are efficiently handled using stacks.
  • Memory efficient: Stacks require only a small amount of additional memory for pointer management.
  • Thread-safety: Using queue.LifoQueue ensures thread-safe operations, making it useful in concurrent applications.
  • Fast performance: collections.deque offers O(1) complexity for push and pop operations, making it an optimal choice.
  • Used in algorithm implementations: Stacks are crucial in algorithms like depth-first search (DFS) and balanced parenthesis checking.
  • Supports various implementations: Python offers multiple ways to implement stacks, catering to different performance and use-case needs.
  • Better performance than lists for stacks: deque outperforms lists when used as a stack due to optimized memory management.
A tutorial on stacks in Python. | Video: codebasics

More on PythonPython Regular Expression re.match() and re.sub() Explained

 

Disadvantages of Stack in Python

  • Limited flexibility: Since stacks operate in LIFO order, accessing elements other than the top element is inefficient.
  • Memory usage: If not managed properly, stacks can cause excessive memory consumption, leading to stack overflow errors.
  • Performance issues with lists: Lists in Python are dynamically resized, which can cause inefficiencies in stack operations.
  • Not suitable for all applications: While stacks are useful for specific scenarios, they are not always the best choice for general data storage.
  • Risk of stack overflow: If recursion depth is too high, it may lead to stack overflow errors in recursive algorithms.
  • Thread synchronization overhead: LifoQueue ensures thread safety, but this comes at the cost of additional overhead in synchronization.
  • No direct index access: Unlike lists, stacks do not allow direct access to arbitrary elements.

Frequently Asked Questions

Python does not have a built-in stack() function, but stacks can be implemented using lists, collections.deque, or queue.LifoQueue. These implementations provide the necessary stack functionalities such as push, pop and peek.

A list is a general-purpose data structure, while a stack follows LIFO principles. Lists can be used as stacks, but they are not optimized for push and pop operations compared to deque or LifoQueue.

A stack is a data structure that operates in a last in, first out (LIFO) manner. It is widely used in computing applications such as memory management, expression evaluation, function call tracking and implementing algorithms like depth-first search.

If performance is a concern, use collections.deque. If thread safety is needed, opt for queue.LifoQueue. If simplicity is preferred, lists work but may not be as efficient.

Explore Job Matches.