How to Implement a Stack Class in Python

A complete Stack class implemented with a Python list, featuring push, pop, peek, is_empty, size, and a readable string representation.

Easy Python 3.6+ Aug 9, 2026 OOP & classes 13 views 0 copies

Python code

45 lines
Python 3.6+
class Stack:
    def __init__(self):
        self._items = []

    def push(self, item):
        """Add an item to the top of the stack."""
        self._items.append(item)

    def pop(self):
        """Remove and return the top item. Raises IndexError if empty."""
        if self.is_empty():
            raise IndexError("pop from empty stack")
        return self._items.pop()

    def peek(self):
        """Return the top item without removing it. Raises IndexError if empty."""
        if self.is_empty():
            raise IndexError("peek from empty stack")
        return self._items[-1]

    def is_empty(self):
        """Check if the stack is empty."""
        return len(self._items) == 0

    def size(self):
        """Return the number of items in the stack."""
        return len(self._items)

    def __str__(self):
        """String representation showing stack from bottom to top."""
        return f"Stack({self._items})"


if __name__ == "__main__":
    stack = Stack()
    stack.push(10)
    stack.push(20)
    stack.push(30)
    print(f"Stack after pushes: {stack}")
    print(f"Size: {stack.size()}")
    print(f"Is empty: {stack.is_empty()}")
    print(f"Peek: {stack.peek()}")
    print(f"Pop: {stack.pop()}")
    print(f"Stack after pop: {stack}")
    print(f"Final size: {stack.size()}")

Output

stdout
Stack after pushes: Stack([10, 20, 30])
Size: 3
Is empty: False
Peek: 30
Pop: 30
Stack after pop: Stack([10, 20])
Final size: 2

How it works

The Stack class uses a private list _items to store elements, with append and pop providing O(1) add/remove at the end, which acts as the top. The push method adds to the end, while pop removes from the end, maintaining LIFO order. The __str__ method returns a readable representation with the bottom-left convention. The guard clauses in pop and peek raise clear IndexError messages to aid debugging. The if __name__ == "__main__" block demonstrates usage without interfering with imports.

Common mistakes

  • Popping or peeking from an empty stack without checking `is_empty`, causing an unclear default error.
  • Using `insert(0, ...)` for push, which makes operations O(n) instead of O(1).
  • Exposing `_items` directly, allowing external code to break the stack invariant.
  • Forgetting to reset the stack when reusing an instance, leading to stale data.

Variations

  1. Use `collections.deque` for thread-safe or double-ended operations.
  2. Add a `__len__` method so `len(stack)` works instead of `stack.size()`.

Real-world use cases

  • Implementing undo/redo functionality in text editors or image tools.
  • Parsing expressions and validating parentheses in compilers and linters.
  • Managing function call stacks in interpreters or tracing recursion depth.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from OOP & classes

Related tutorials and quizzes for this topic.