Board Formulas
🐍 PythonπŸ“… Day 19

Stack in Python (Using a List)

Build a stack (last in, first out) with a Python list: push, pop, peek and isEmpty, overflow and underflow, and a complete menu-driven program.

🎯

Learning objectives

  • β†’Explain the LIFO principle with everyday examples
  • β†’Implement push, pop, peek and isEmpty using a list
  • β†’Detect underflow (removing from an empty stack) and overflow (adding to a full one)
  • β†’Write a menu-driven stack program

πŸ’‘ Key points

  • A stack is LIFO β€” Last In, First Out. Like a pile of plates, you add and remove only at the top.
  • With a list, the END of the list is the top: append() pushes and pop() pops.
  • Peek (also called top) reads stack[-1] without removing it.
  • isEmpty is len(stack) == 0, or simply not stack.
  • Underflow: trying to pop or peek when the stack is empty. Always check isEmpty first, or list.pop() raises IndexError.
  • A Python list grows as needed, so overflow only happens when you set a maximum size yourself.
  • Stacks power undo in editors, the browser's Back button, reversing data and checking matching brackets.

πŸ’» Code examples(6)

#1Stack basics with a list
python
stack = []
stack.append(10)       # push
stack.append(20)
stack.append(30)
print(stack)           # top is on the right
print(stack[-1])       # peek
print(stack.pop())     # pop removes the top
print(stack)
Output
[10, 20, 30]
30
30
[10, 20]
30 went in last, so it comes out first. append() and pop() both work at the end of the list, which is fast.
#2push, pop, peek and isEmpty as functions
python
def isEmpty(stk):
    return len(stk) == 0

def push(stk, item):
    stk.append(item)

def pop(stk):
    if isEmpty(stk):
        return "Underflow"
    return stk.pop()

def peek(stk):
    if isEmpty(stk):
        return "Underflow"
    return stk[-1]

books = []
push(books, "Maths")
push(books, "Physics")
print(peek(books))
print(pop(books))
print(pop(books))
print(pop(books))       # nothing left
print(isEmpty(books))
Output
Physics
Physics
Maths
Underflow
True
Passing the list into each function keeps the code reusable for any stack. Checking isEmpty() first turns a crash into a clear message.
#3Overflow with a fixed-size stack
python
MAX = 3
stack = []

def push(item):
    if len(stack) == MAX:
        print("Overflow! Cannot push", item)
    else:
        stack.append(item)
        print("Pushed", item)

for x in [11, 22, 33, 44]:
    push(x)
print(stack)
Output
Pushed 11
Pushed 22
Pushed 33
Overflow! Cannot push 44
[11, 22, 33]
Real memory is limited, so some stacks have a fixed capacity. Comparing the length with MAX before pushing detects overflow.
#4Push selected items, then pop them all
python
marks = {"Amit": 87, "Priya": 72, "Ravi": 91,
         "Neha": 65, "Karan": 80}
stack = []

def push_toppers(d):
    for name in d:
        if d[name] > 75:
            stack.append(name)

def pop_all():
    while stack:
        print(stack.pop())
    print("Stack empty")

push_toppers(marks)
pop_all()
Output
Karan
Ravi
Amit
Stack empty
Names scoring above 75 are pushed in the order they appear in the dictionary and popped in reverse. while stack: keeps going until the list is empty.
#5Application: checking brackets
python
def balanced(expr):
    pairs = {")": "(", "]": "[", "}": "{"}
    stk = []
    for ch in expr:
        if ch in "([{":
            stk.append(ch)
        elif ch in pairs:
            if not stk or stk.pop() != pairs[ch]:
                return False
    return not stk      # True if nothing is left

print(balanced("(a+b)*[c-d]"))
print(balanced("(a+b]"))
print(balanced("((a)"))
Output
True
False
False
Every opening bracket is pushed. Each closing bracket must match the one on top. Leftover brackets at the end mean something was never closed.
#6Menu-driven stack program
python
stack = []
print("1.Push 2.Pop 3.Peek 4.Display 5.Exit")
while True:
    ch = input("Choice: ")
    if ch == "1":
        stack.append(int(input("Item: ")))
    elif ch == "2":
        if stack:
            print("Popped", stack.pop())
        else:
            print("Underflow: stack is empty")
    elif ch == "3":
        print("Top:", stack[-1] if stack else None)
    elif ch == "4":
        print(stack[::-1])      # top first
    elif ch == "5":
        print("Bye")
        break
    else:
        print("Invalid choice")
Output
1.Push 2.Pop 3.Peek 4.Display 5.Exit
Choice: 1
Item: 10
Choice: 1
Item: 20
Choice: 4
[20, 10]
Choice: 2
Popped 20
Choice: 3
Top: 10
Choice: 2
Popped 10
Choice: 2
Underflow: stack is empty
Choice: 5
Bye
Sample run: the numbers after each prompt are what the user typed. The loop repeats until the user chooses 5.

🎯 Practice

Q1. What does LIFO stand for?+

Last In, First Out: the item added most recently is the first one removed.

Q2. Start with an empty stack: push 5, push 8, pop, push 3, push 9, pop. What is the stack now, and what is on top?+

[5, 3], with 3 on top.

Q3. What is underflow, and how do you prevent it?+

Underflow is trying to pop or peek an empty stack. Check isEmpty() (or if stack:) before popping; otherwise list.pop() raises IndexError: pop from empty list.

Q4. Write PUSH(N) that pushes only the even numbers from the list N onto a stack named st.+

st = [] def PUSH(N): for x in N: if x % 2 == 0: st.append(x) PUSH([3, 8, 5, 12, 6]) print(st) # [8, 12, 6]

Q5. Why do we use the end of the list as the top, and not the start?+

append() and pop() at the end are fast. insert(0, x) and pop(0) at the start have to shift every other item along.

πŸ“ Notes

Picturing a stack

push 10, 20, 30       then pop

  | 30 | <- top
  | 20 |              | 20 | <- top
  | 10 |              | 10 |
  +----+              +----+

Only the top is ever touched. To reach 10, you must first pop 30 and 20.

Stack operations and their list code

  • push(x) β†’ stack.append(x)
  • pop() β†’ stack.pop() (check it is not empty first)
  • peek() / top() β†’ stack[-1]
  • isEmpty() β†’ len(stack) == 0 or not stack
  • size() β†’ len(stack)
  • display β†’ stack[::-1] prints the top first

Textbooks often name the empty check isEmpty(). Following PEP 8 from Day 3, you could also call it is_empty(); both work the same.

Where stacks are used

  • Undo in a text editor: each change is pushed; undo pops the latest one.
  • Back button in a browser: visited pages are pushed; Back pops.
  • Function calls: Python keeps a call stack, which is why a traceback lists the calls in order.
  • Reversing: push every character of a word, then pop them all.

Common mistakes

  • Using pop(0): that removes from the bottom, which turns the structure into a queue (first in, first out).
  • Forgetting the empty check: [].pop() raises IndexError: pop from empty list.
  • Peeking with pop(): stack.pop() removes the item; use stack[-1] to look without removing.
  • Using a local list by mistake: if stack = [] is written inside push(), a new empty list is created on every call.

Next: Day 20 β€” Inheritance in Python, where classes start reusing each other's code.